Compare commits

...

62 Commits

Author SHA1 Message Date
Dustin L. Howett
f4327f32f6 Migrate spelling-0.0.21 changes from main 2022-08-10 23:42:07 +02:00
Leonard Hecker
296e1834fd wip 2022-08-10 23:42:07 +02:00
Rémy Jacquin
b55bcb50d9 Add VC++ v14 Framework dependency note (#13625)
## Summary of the Pull Request
VC++ v14 Descktop Framework package is required and not installed automatically when installing package manually.

## PR Checklist
* [X] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
2022-08-09 15:43:24 +00:00
Leonard Hecker
2c922e105c Clean up TSFInputControl a bit (#13677)
While working on #13398 I felt that `TSFInputControl` wasn't up to sniff.
This commit is a minor cleanup of the class:
* default member initializers
* Simplified use of STL classes which already perform boundary checks
* Correctly check text buffer emptiness in `_SendAndClearText`
* Track selection range as mandated by the API

## Validation Steps Performed
* Japanese IME (Full-Width Katakana)
  Typing "saitama" produces "サイタマ" 
* Korean IME
  Typing "gksrmf" produces "한글" 
* Vietnamese IME
  Typing "xin chaof" continues to produce broken "xin xinchaof"
  (It's supposed to produce "xin chào")
* Emoji Picker (Win+.)
  
2022-08-08 13:51:46 -05:00
Leonard Hecker
768d4b59ca Replace result codes with exceptions in JumpList (#13688)
This commit simplifies `Jumplist::UpdateJumplist` by using exceptions 
instead of returning error codes. Otherwise the code is identical to before.
2022-08-08 13:10:48 +00:00
Mike Griese
210a98e449 Fix conpty not emitting colored spaces on the VERY FIRST frame (#13665)
This bug arose from a "race condition" in the first frame handling of conpty. We'd try to optimize out spaces if we've cleared the entire frame (which always happens on the first frame). However, doing that even for colored spaces meant that things like powerline prompts could be emitted to conhost during the first frame, and we'd optimize the spaces out. That's silly. 

This is hard to repro naturally, but this comment has another repro I used
https://github.com/microsoft/terminal/issues/8341#issuecomment-731310022

Modified to facilitate simpler testing, it looks like:

#### Before
![image](https://user-images.githubusercontent.com/18356694/182680119-bb22179c-a328-43f3-b64a-0d1d5773b813.png)

#### After
![image](https://user-images.githubusercontent.com/18356694/182680159-805964c5-c4cc-411a-8865-3866fca8d6e9.png)


* [x] Closes #8341
* [x] Tests added

Co-authored by @DHowett
2022-08-08 11:48:04 +00:00
Mike Griese
ffe9a0f09b Fix the ConPTY extended attributes optimization (#13661)
... which should have never worked in the first place


Quick filing a PR for review. This is the bulk of the actual code changes. Figured it was best to review the conpty changes sooner than later and I can add tests in the morning.

Test cases:
```
printf "\e[7m         test         \e[m\n"
```

```
printf "\e[7m"; printf ' %.0s' $(seq 1 $COLUMNS); printf "\e[m\n"
```

After:
![image](https://user-images.githubusercontent.com/18356694/182478185-6e65ab99-5c27-4772-af3b-2baa22387ec1.png)


Closes #13229


Definitely fixes:
* [x] #13643
* [x] https://github.com/PowerShell/PowerShell/issues/17812
2022-08-05 19:31:11 +00:00
PankajBhojwani
ba08dd2174 Use only one tab color picker for all tabs, delay load it (#13674)
## Summary of the Pull Request

- We only ever have 1 color picker now, instead of each tab having its own
- `TerminalPage` constructs this color picker (upon first request for it)
- `TerminalPage` attaches the color picker to the tab that requested for it
- `TerminalTab` detaches the color picker when it is done with it, so that `TerminalPage` can attach it to another tab later on

## References
#5907 

## Validation Steps Performed
User-end behaviour is the same
2022-08-05 19:13:57 +00:00
Leonard Hecker
74cdffe921 Fix input corruption for high code points (#13667)
We must use 65535 as `MAX_PARAMETER_VALUE` in order for us to properly parse
win32-input-mode sequences, which transmit UTF-16 characters as parameters.

Closes #12977

## Validation Steps Performed
* Call `SendInput` with 🙁 (`L'\xD83D'`, `L'\xDE41'`)
* 🙁 appears on the input line 
2022-08-04 22:10:05 +00:00
PankajBhojwani
1a7783449c Fix _isDefTermSession not propagating upon pane split/close (#13649)
## Summary of the Pull Request
In #13560 we added a member to `Pane` that lets it know if it was spawned as a default terminal session, but did not propagate that value when the pane gets split or when the pane closes. This commit fixes that. 

## Validation Steps Performed
A session spawned by a def term invocation remembers it even as it goes through splits
2022-08-04 01:34:31 +00:00
Carlos Zamora
a9c3b7724c Scroll to top when select all action is invoked (#13656)
## Summary of the Pull Request
In general, when a selection marker is shown, we should scroll to it. The `selectAll` action adds a selection marker, but we don't scroll to it. This PR makes it such that we do do that.

Epic: #4993 
Closes #13485
2022-08-02 20:49:48 +00:00
Carlos Zamora
61d84a7023 [Schema] Move scroll mark settings from global to profile settings (#13655)
Updates the schema such that the scroll mark settings are defined as profile settings instead of global settings (because they're actually profile settings).

Separately (but still relevant), I've also updated the release notes.

Closes #13583
2022-08-02 13:04:04 -07:00
Leonard Hecker
d5212021ff GdiEngine: Invalidate entire rows at a time (#13638)
This fixes an issue were overwriting parts of a row would only trigger
that specific portion of the row to be redrawn. This isn't just
problematic for combining characters, but also for things like
the new `TestDbcsBisectWriteCells` test introduced in #13626.

Benchmarks showed no impact on performance whatsoever.

## Validation Steps Performed
* Pick this commit into #13626
* Run the `TestDbcsBisectWriteCells` test and break before OpenConsole exits
* A correct "QいかなZYXWVUTに" output is visible 
2022-08-02 19:55:36 +00:00
Leonard Hecker
55f1b8d2c9 AtlasEngine: Recognize Powerline glyphs (#13650)
This commit makes AtlasEngine recognize Powerline glyphs as box drawing ones.
The extra pixel offsets when determining the `scale` caused weird artifacts
and thus were removed. It seems like this causes no noticeable regressions.

Closes #13029

## Validation Steps Performed
* Run all values of `wchar_t` through `isInInversionList`
  and ensure it produces the expected value 
* Powerline glyphs are correctly scaled with Cascadia Code PL 
2022-08-02 17:00:18 +00:00
Leonard Hecker
7f922076e7 Fix a crash on settings reload (#13644)
07d58a8 contains a regression where the settings' `Themes()` property is
accessed without checking whether it's a `nullptr`. This can happen because
the invalid settings modal is shown with a empty settings model object.

This commit fixes the issue by deferring the update of `_settings` until
after we ensured that the `_settings` object is valid (besides warnings).

Closes #13543

## Validation Steps Performed
* Replace any string value with `123`
* Application doesn't crash 
2022-08-02 16:58:46 +00:00
PankajBhojwani
7976e48195 Fix a couple of issues with color scheme MVVM (#13646)
## Summary of the Pull Request
- When 'discard changes' is hit, we re-initialize our list of color scheme view models but forgot to tell xaml about it, this commit fixes that. 
- Make sure to exit rename mode when 'update settings' gets called

## References
color schemes mvvm added in #13179 

## PR Checklist
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [x] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx

## Validation Steps Performed
Hitting discard changes doesn't cause an inconsistency with the currently selected scheme anymore
2022-08-02 02:23:32 +00:00
PankajBhojwani
89d57e827e [DxD] Add 'Automatic' as a mode for CloseOnExit (#13560)
## Summary of the Pull Request
Adds a new mode to `CloseOnExit`: `Automatic`. In this mode, if a process handed off by defterm terminates for whatever reason, we always close (i.e. we treat the mode as `Always`), but for processes launched by Terminal we terminate as with the `Graceful` behaviour. 

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

## Detailed Description of the Pull Request / Additional comments

- Adds a new enum value to `CloseOnExit`
- Adds a new function to `Pane`: `FinalizeConfigurationGivenDefault`: this is a function that should be called when the pane is created via default terminal handoff, and can contain any special configurations we should set given that the pane was created via handoff

## Validation Steps Performed
2022-08-01 21:11:18 +00:00
Mike Griese
d1fc11248c Restore the ability for alt+tab to restore the Terminal after minimizing with taskbar (#13624)
Curiously, at least on Windows 10 (and rarely on Windows 11), if you minimize the Terminal by clicking on the taskbar, then alt-tab to try and restore the window, the Taskbar will decide to call `SwitchToWindow` on the invisible, owned ConPTY window instead of the main window. When that happens, ConPTY'll get a `WM_SIZE(SIZE_RESTORED, lParam=0)`. The main window will NOT get a `SwitchToWindow` called. If ConPTY doesn't actually inform the hosting process about this, then the main HWND might stay hidden.

* Refer to #13158 where we disabled this.
* Closes #13589
* Closes #13248
* Tested manually on a Windows 10 VM.
* Confirmed that opening tabs while maximized/snapped doesn't restore down.
* `[Native]::ShowWindow([Native]::GetConsoleWindow(), 6)` still works
2022-08-01 20:33:56 +00:00
Mike Griese
523bd17cb7 the the 2022-08-01 14:15:00 -05:00
Mike Griese
3d40c43f5b Add support for hiding the tab close button (#13348)
## Summary of the Pull Request

Adds support for the `tab.showCloseButton` property to themes. This accepts three values:

* `"always"` (default): The close button acts like it does today.
* `"hover"`: The close button is always visible on the active tab. On inactive tabs, the close button only appears on mouse over. 
* `"never"`: The close button is never visible. You can't close the tab with middle-click, but you can still use keyboard shortcuts to close the tab.

## References
* See #3327 
* ⚠️ targets #13178 ⚠️


## PR Checklist
* [x] Closes #3335
* [x] I work here
* [ ] Tests added/passed
* [n/a] Requires documentation to be updated - YUP

## Detailed Description of the Pull Request / Additional comments

See the following two properties in WInUI that we're leveraging here. 

* [`TabViewCloseButtonOverlayMode.OnPointerOver`](https://docs.microsoft.com/en-us/windows/winui/api/microsoft.ui.xaml.controls.tabviewclosebuttonoverlaymode?view=winui-2.7&viewFallbackFrom=winui-2.2)
* [`TabViewItem.IsClosable`](https://docs.microsoft.com/en-us/windows/winui/api/microsoft.ui.xaml.controls.tabviewitem.isclosable?view=winui-2.2#microsoft-ui-xaml-controls-tabviewitem-isclosable)

One is a tabview-level property, the other is a per-tab-item property, hence why this code is a little wacky. 

## Validation Steps Performed

gifs below
2022-08-01 17:20:15 +00:00
Leonard Hecker
a84f4d5b10 AtlasEngine: Scale glyphs to better fit the cell size (#13549)
This commit contains 3 improvements for glyph rendering:
* Scale block element and box drawing characters to fit the cell size
  "perfectly" without leaving pixel gaps between cells.
* Use `IDWriteTextLayout::GetOverhangMetrics` to determine whether glyphs
  are outside the given layout box and if they are, offset their position
  to fit them back in. If that still fails to fit, we downscale them.
* Always scale up glyphs that are more than 2 cells wide
  This ensures that long ligatures that mimic box drawing characters like
  "===" under Cascadia Code are upscaled just like regular box drawings.
  Unfortunately this results in ligature-heavy text (like Myanmar) to get an
  "uneven" appearance because some ligatures can suddenly appear too large.
  It's difficult to come up with a good heuristic here.

Closes #12512

## Validation Steps Performed
* Print UTF-8-demo.txt
* Block characters don't leave gaps 
* Print a lorem-ipsum in Myanmar
* Glyphs aren't cut off anymore 
* Print a long "===" ligature under Cascadia Code
* The ligature is as wide as the number of cells used 
2022-08-01 15:41:58 +00:00
Mike Griese
64ca898ea5 Fix the build when the solution dir has spaces (#13627)
Closes #13354
2022-07-29 19:54:45 +00:00
PankajBhojwani
df671377d5 Implement MVVM for Color Schemes (#13179)
## Summary of the Pull Request
Implements the MVVM style for the Color Schemes editor

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

## Detailed Description of the Pull Request / Additional comments
Introduces:
- `ColorSchemesPageViewModel`: The view model responsible for the entire color schemes page. Handles what the current scheme is, adding/deleting/renaming schemes
- `ColorSchemeViewModel`: A view model class for individual color schemes

## Validation Steps Performed
Manually tested:
- Edit a color scheme
- Add new color scheme
- Rename a color scheme
- Delete a color scheme
2022-07-29 17:11:29 +00:00
Mike Griese
5c35a64bb3 Hopefully fix the HandleCommandlineArgs crashes (#13604)
This is an experiment, as discussed in https://github.com/microsoft/terminal/issues/11790#issuecomment-1179143049. We don't know what for sure causes these crashes, but it seems that blindly throwing, so that it gets picked up by Watson, is probably not the move. Instead, we're just gonna do our fallback, REGARDLESS of what the exception was.



See #11790, MSFT:38542548, MSFT:38572983, MSFT:38542574 et. al.
2022-07-29 11:27:34 +00:00
Mike Griese
b3604ba0eb Manually quit when the OS tells us to update (#13614)
Refer to https://docs.microsoft.com/en-us/windows/win32/rstmgr/guidelines-for-applications

The OS will send us a WM_QUERYENDSESSION when it's preparing an
update for our app. It will then send us a WM_ENDSESSION, which gives
us a small timeout (~30s) to actually shut down gracefully. After
that timeout, it will send us a WM_CLOSE. If we still don't close
after the WM_CLOSE, it'll force-kill us (causing a crash which will be
bucketed to moapphang).

We will manually start a quit, so that we can persist the state. If we refuse to
gracefully shut down, the OS will crash us to focefully terminate us. We
choose to quit here, rather than just close, to skip over any warning dialogs
(e.g. "Are you sure you want to close all tabs?") which might prevent a WM_CLOSE
from cleanly closing the window.

This will cause a appHost._RequestQuitAll, which will notify the
monarch to collect up all the window state and save it.

This "crash" caused by the OS force killing us constitutes 80% of all our crashes. 80%. See MSFT:38947155, MSFT:38877540, MSFT:21058878, MSFT:31710054, MSFT:39764652, MSFT:26883776.

Closes #13569


It also fixes the issue where if you've got Terminal Dev running (outside VS), and you try to Deploy, you have to make sure to close the "Are you sure you want to close all tabs" dialog before the deployment can proceed. A deploy in VS sends the same sequence of messages as a real update.
2022-07-29 11:21:01 +00:00
Mike Griese
781340a702 Don't comment on commits, cause no one's using that (#13616)
As discussed on teams. 

Refer to https://github.com/check-spelling/check-spelling/issues/23#issuecomment-1195826414
2022-07-28 21:16:45 +00:00
Leonard Hecker
4e5a0c137b Remove outdated MSVC checks (#13621)
This removes outdated checks for MSVC versions that we don't support anymore.
2022-07-28 18:11:12 +00:00
Leonard Hecker
2470805aa0 AtlasEngine: Implement remaining grid lines (#13587)
This commit implements the remaining 5 of 8 grid lines:
left/top/right/bottom (COMMON_LVB) borders and double underline

`AtlasEngine::_resolveFontMetrics` was partially refactored to use `float`s
instead of `double`s, because that's what the remaining code uses as well.
It also helps the new, slightly more complex double underline calculation.

## Validation Steps Performed
* Print characters with the `COMMON_LVB_GRID_HORIZONTAL`, `GRID_LVERTICAL`,
  `GRID_RVERTICAL` and `UNDERSCORE` attributes via `WriteConsoleOutputW`
* All 4 grid lines are visible 
* Grid lines correctly scale according to the `lineWidth` 
* Print a double underline with `printf "\033[21mtest\033[0m"`
* A double underline is fully visible 
2022-07-28 13:34:51 +00:00
Mike Griese
73e7fd16d6 Two sets of localtest fixes for July 2022 (#13603)
Cleans up a couple local test failures.

* [x] Closes #13474: So, I clearly hadn't ran the local tests at the end of the themes PR. We needed a sensible fallback to SOME theme, even if there wasn't one provided in the user json. This is only really hit in the tests (that don't also include `defaults.json`.
* [x] Closes #13323: Meh, the ordering of the keys in this test doesn't matter. Ordering is a map implementation detail. This is fine.
* [x] Ran tests locally
2022-07-27 19:39:51 +00:00
Leonard Hecker
17db409e7a AtlasEngine: Remove support for Windows 7 (#13608)
We recently figured that we can drop support for Windows 7. Coincidentally
AtlasEngine never actually supported Windows 7 properly, because it called
`ResizeBuffers` with `DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT`
no matter whether the swap chain was created with it enabled.

The new minimally supported version is Windows 8.1.
2022-07-27 16:23:55 +00:00
LitoMore
e20346a558 Use GitHub built-in style for notes (#13615)
Update the `note` prefix for blockquotes with GitHub built-in styles.

## References
- https://github.com/community/community/discussions/16925

## PR Checklist
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
2022-07-27 09:12:13 -07:00
Leonard Hecker
65b71ff498 AtlasEngine: Fix LRU state after scrolling (#13607)
66f4f9d had another bug: Just like how we scroll our viewport by `memmove`ing
the `_r.cells` array, we also have to `memmove` the new `_r.cellGlyphMapping`.
Without this fix drawing lots of glyphs while only scrolling slightly
(= not invalidating the entire viewport), would erroneously call
`makeNewest` on glyphs now outside of the viewport. This would cause
actually visible glyphs to be recycled and overwritten by new ones.

## Validation Steps Performed
* Switch to Cascadia Code
* Print some text that fills the glyph atlas
* Scroll down by a few rows
* Write a long "==========" ligature (this quickly fills up
  any remaining space in the atlas and exacerbates the issue)
* Unrelated rows don't get corrupted 
2022-07-27 13:42:38 +00:00
Leonard Hecker
b0396f1741 Make ToolsVersion more consistent in our project files (#13535)
While working on another PR related to this I noticed that my VS
generates `.vcxproj` files that are a bit different to the ones we have.
This commit is a quick search & replace of all our project files to make
(primarily) their `ToolsVersion` more in line with what VS does itself:
No `ToolsVersion` for `.vcxproj`, `ToolsVersion="15.0"`
for `.csproj` and `ToolsVersion="4.0"` for `.filters` files.
2022-07-26 22:31:42 +00:00
PankajBhojwani
d9df27ffa4 Improve Launch MVVM (#13467)
## Summary of the Pull Request
The xaml file no longer directly accesses the settings model object, and the settings model object is no longer exposed on the view model

## References
#13377 

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

## Validation Steps Performed
Still works
2022-07-26 22:05:27 +00:00
Sergey
47137648e3 Rename newTabPosition values (#13602)
Renames `newTabPosition` strings and enums.
Also fixes the schema, noted in https://github.com/microsoft/terminal/pull/13469#discussion_r928138496

Closes #13597
2022-07-26 21:18:06 +00:00
Mike Griese
6c2316df44 Add some notes on building package from commandline (#13350)
I was messing around with trying to build & deploy from the commandline. I discovered this, which is progress. However, the inner-loop commandline build for the Terminal is still egregiously long. 

* just a docs update
* is EIM work
2022-07-26 06:39:21 -05:00
Leonard Hecker
feabe41a08 AtlasEngine: Handle IntenseIsBold (#13577)
This change adds support for the `IntenseIsBold` rendering setting.
Windows Terminal for instance defaults to `false` here, causing
intense colors to only be bright but not bold.

## Validation Steps Performed
* Set "Intense text style" to "Bright colors"
* Enable AtlasEngine
* Print ``echo "`e[1mtest`e[0m"``
* "test" appears as bright without being bold 
2022-07-25 21:54:43 +00:00
Dustin L. Howett
2e8949d3e8 Spellbot: ignore ploc* in lowercase (#13576) 2022-07-22 18:14:11 -05:00
Carlos Zamora
f04ebbe9b6 Introduce Mark Mode spec (add-on) (#5804)
## Summary of the Pull Request
This is a spec specifically dedicated to Mark Mode. It's an addition to the Keyboard Selection spec. I felt that it makes the most sense to make this a separate PR because there's a lot of ideas that are very specific to Mark Mode, and this gives us the space to modify some of that behavior and get a good look at how other terminal emulators designed this feature.

## References
#2840 - Keyboard Selection Spec (base spec/branch/PR)

## PR Checklist
* [X] Contributes to #715
2022-07-22 18:08:08 -05:00
Leonard Hecker
8a26f141c8 Introduce breaking changes to ReadConsoleOutput (#13321)
#8000 will change the way we store text from a strict grid/matrix where
one UTF16 character or surrogate pair always equals 1 column with the
possibility of joining exactly 2 to a wide character pair, to a dynamic
buffer where 1 or more characters can form 1 or more columns in any
arbitrary combination. Our long term goal is to properly support both
complex grapheme clusters like Emojis and complex ligatures that a wider
than 2 columns.  This change requires us to break our API as
`ReadConsoleOutputA/W` assumes the existence of exactly this grid/matrix
storage. Since we store wide characters like "い" as a single codepoint
that is simply marked as being 2 columns wide in the future, we cannot
reconstruct trailing DBCS characters that were written to the buffer
like we used to.  On the other hand this new behavior allows us to
implement better Unicode support and most likely significantly improve
our performance.

### Minor breaking changes

* `ReadConsoleOutputA` will now always **zero** the high byte in
  `(CHAR_INFO).Char.UnicodeChar`. Only the `.AsciiChar` can be used
  then. This prevents users from storing "additional" data in the
  terminal buffer.
* `ReadConsoleOutputA` will now **zero** the `.AsciiChar` if it fails to
  convert the Unicode character into an appropriate DBCS.
  * Example: It's possible to write "い" into a narrow column despite
    being a wide character. In these cases `WriteConsoleOutputA` will
    now return `0x00` instead of `0x44` (the lower half of い's code
    point `0x3044`).

### Major breaking changes

* `ReadConsoleOutputW` will now repeat the leading Unicode character
  twice and ignore the trailing one.
  * Example 1: Writing the pair `0x3044 0xabcd` with
    `WriteConsoleOutputW` used to yield the same `0x3044 0xabcd` if read
    back with `ReadConsoleOutputW`. This worked because conhost
    effectively ignored the trailing codepoint, allowing one to
    "smuggle" data. In the future this trailing character will be
    discarded and produce `0x3044 0x3044` instead.
  * Example 2: Writing い with `WriteConsoleOutputA` can be done with
    code page 932 (Shift-JIS) and the DBCS `0x82 0xa2`. If read back
    with `ReadConsoleOutputW` this would previously yield the two
    Unicode characters `0x3044 0xffff`. After this commit it'll yield
    `0x3044 0x3044`.

### Alternative approaches

It's possible to "tag"/"mark" written data as originating from
`WriteConsoleOutputA/W` so that it can be reconstructed accurately later
on. However this lead to implementation complexities that we're actively
trying to avoid in the new buffer implementation. Effectively
_everything_ that touches the buffer's text would have to handle these
marks and either write or clear them. Given the most likely small amount
of users who depend on the current quirky behavior, it'd be an
unwarranted maintenance and performance burden and prevent Windows
Terminal to ever truly migrate to full Unicode support.

## Validation Steps Performed
* Adjusted feature tests complete successfully 
2022-07-22 23:02:18 +00:00
Dustin L. Howett
bb40efc00b Lock the app names in the pseudoloc locales (#13563)
On occasion, when we submit to the store we get a package rejection
because the app name has changed for the `qps-*` locales. Instead of
constantly reserving new pseudolocalized app names every time the
pseudolocalization seed changes, we should just lock our app name so
that it does not get pseudolocalized.
2022-07-22 18:02:03 +00:00
Josh Soref
9fbdf37647 Upgrade check-spelling to v0.0.20 (#13565)
Upgrade check-spelling to [v0.0.20](https://github.com/check-spelling/check-spelling/releases/tag/v0.0.20)

This upgrade includes a refresh of the workflow

key new features:
* the previous comment is collapsed
* duplicate words are flagged (see `alone` and `the`)
* forbidding patterns (see `nonexistent`, `preexisting`, and `greater than`)

Each of these features can be tuned
- comment collapsing is controlled by the `followup` bits in the workflow--  but I can't imagine why one would want to turn it off
- duplicate words can be masked in `patterns.txt` (see `Guid` and `that`)
- forbidding patterns (especially duplicates) is in `.github/actions/spelling/line_forbidden.patterns`

Fwiw, I'm slowly moving towards not using `.txt` in filenames, but it's a long term project and I have a bunch of other goals for the near term.

The refresh of advice is of course flexible -- I'm still evolving my default text. Note that the default now includes some `curl` and I'm still working on how I want to consume the output. I'm getting close to the point where I might be able to provide a tool that could reliably consume the output (including on Windows).

This code has been used internally for a while, but I tested it for this repository here:
https://github.com/check-spelling/terminal/pull/2
2022-07-22 13:01:32 -05:00
PankajBhojwani
d3ae00e2f3 Change AdjustIndistinguishableColors to an enum setting instead of a boolean setting (#13512)
## Summary of the Pull Request
`AdjustIndistinguishableColors` can now be set to:

- `Never`: Never adjust the colors
- `Indexed`: Only adjust colors that are part of the color scheme
- `Always`: Always adjust the colors

## References
#13343

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

## Detailed Description of the Pull Request / Additional comments
For legacy purposes, `true` and `false` map to `Indexed` and `Never` respectively

## Validation Steps Performed
Setting still works
2022-07-22 11:41:15 +00:00
Mike Griese
5ea25f1883 Fix a crash when showTabsInTitlebar:false (#13561)
Does what it says on the tin.
2022-07-22 11:19:12 +00:00
Dustin L. Howett
45b1cde0bc Remove the api-ms-win-core-synch-l1-2-0 Windows 7 shim (#13517)
Per the VS 2022 documentation, Terminal is no longer supported on Windows 7.
We don't need to carry this baggage around.

It was introduced in #10559.
2022-07-19 20:12:23 +00:00
Jeroen B
03378690d8 Make cmd palette 'go back' button return to previously selected action (#13504)
The behaviour of the 'go back' button in the command palette was changed to return to the previously selected element rather than the root.

Instead of returning to the root, the go back button now returns to the previously selected item in the filtered action list. The previously selected item is selected by default and the view is scoped to the item.

## Validation Steps Performed
Manually tested by going back and forth between nested actions in the command palette.

Closes #13457
2022-07-19 20:05:19 +00:00
AdamSotak
e7a79d9c9e Added Source Code and Send Feedback buttons to About dialog (#13510)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
Added two new buttons to the About dialog. Source Code and Send Feedback buttons link directly to the Terminal project on GitHub and to the Issues page respectively.

<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> 
## References
#13371

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

<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Performed manual testing and confirmed that the implementation works.
2022-07-19 19:59:02 +00:00
Leonard Hecker
784e4ec93a AtlasEngine: Improve robustness against TextBuffer bugs (#13530)
The current TextBuffer implementation will happily overwrite the
leading/trailing half of a wide glyph with a narrow one without
padding the other half with whitespace. This could crash AtlasEngine
which aggressively guarded against such inconsistencies.

Closes #13522

## Validation Steps Performed
* Run .bat file linked in #13522
  (Override wide glyph with a single space.)
* `AtlasEngine` doesn't crash 
2022-07-19 19:27:28 +00:00
Leonard Hecker
d2b77509f1 Fix VS version for compliance build (#13534)
#13368 (bd403dc) failed to increment the VS version
in our compliance pipeline which broke it.
2022-07-19 17:00:02 +00:00
Leonard Hecker
67662e1a6a AtlasEngine: Fix bugs introduced in 66f4f9d and d74b66a (#13496)
### Disappearing glyphs

We only process glyphs within the dirtyRect, but glyphs outside of the dirtyRect
are still in use and shouldn't be discarded. This is critical if someone uses
a tool like tmux to split the terminal horizontally. If they then print a lot
of Unicode text on just one side, we have to ensure that the (for example)
plain ASCII glyphs on the other half of the viewport are still retained.

### Black viewport after font changes

The cursor was drawn without a clip rect, causing the entire atlas
texture to be filled with black. This just so happened to work fine 
in Windows Terminal but relied on a race condition.

Closes #13490

## Validation Steps Performed
* Disappearing glyphs
  * Start `tmux` in `wsl`
  * Split horizontally with `Ctrl+B`, `"`
  * `cat` a huge Unicode text file on the bottom
  * Ensure ASCII glyphs in the top half don't disappear 
* Black viewport after font changes
  * Start `OpenConsole` with `AtlasEngine`
  * Open Properties dialog and click "Ok"
  * Viewport content doesn't disappear 
2022-07-15 21:08:59 +00:00
Leonard Hecker
5926cc29e2 Fix bad code in fuzzing_directed.h (#13505)
2b202ce6 changed this code to fix 2-phase name lookup, but accidentally
changed `&m_tInit` to `&CFuzzType::m_tInit` (pointer-to-member¹)
instead of `&this->m_tInit` (a regular pointer to some value).
This should not be confused with `&(CFuzzType::m_tInit)`
of course which is _not_ a pointer-to-member.

¹ To simplify things, a pointer-to-member is basically the byte offset of a
member within a struct. For instance given `struct T { char a, b, c, d; }` then
`&T::c` would commonly "store" the value 2, equivalent to `offsetof(T, c)`.

Closes #13501
2022-07-14 19:32:05 +00:00
Sergey
2f58711ee6 Updated schema with newTabPosition setting (#13469)
## Summary of the Pull Request
Updates schema with newTabPosition global setting, added in #13421

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

## Detailed Description of the Pull Request / Additional comments
#13421 got merged, so I'm adding this one

Co-authored-by: Carlos Zamora <carlos.zamora@microsoft.com>
2022-07-14 10:47:31 -07:00
PankajBhojwani
2c6cdc281f Re-enable the setting to adjust the colors of indistinguishable text (#13343)
## Summary of the Pull Request
Re-enable the setting to adjust indistinguishable text, with some changes:

- We now pre-calculate the nudged values for 'default bright foreground' as well
- When a color table entry is manually set (i.e. via VT sequences) we re-calculate the nudged values

## References
#11095 #12160

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

## Validation Steps Performed
Indistinguishable text gets adjusted again
2022-07-14 15:58:11 +00:00
Mike Griese
a17f18a920 fix spelling in post 2022-07-14 06:36:37 -05:00
dansmor7
67f6b29d63 Update caption buttons to use glyphs (#13341)
The min/max/close buttons now use the same font glyphs used in Windows instead of paths.
They will also look different depending on whether you use Windows 10 or 11.

With certain scaling levels, the new fluent icons are always blurry on titlebars (win32, UWP, terminal).
I didn't check, but I assume that the glyphs will not be blurry on Windows 10 because they use the old font.
However, the glyps seem to have some alignment issues, making them even more blurry, and I'm not sure if I can fix that.

I looked into the minimize button problem:
* The UWP titlebar has 4px/5px, just like Terminal, but win32 titlebars have 5px/4px
* The new fluent icons have rounded caps, but the win32 minimize one doesn't (it's very subtle)
* The win32 minimize button is not blurry when the other buttons are

From this I presume that the minimize button is still using the old icon. So perhaps the Terminal/UWP vertical alignment is correct.

I was able to improve the rendering by wrapping the icon inside a Viewbox.

However, it won't perfectly match UWP, because scaling is calculated differently.
The icon width is 10px, which on 1.25x scaling would become 12.5px.
UWP titlebars truncate that to 12px, while Xaml renders that as 13px.

This is probably the best that can be done for now.

I found these icons [here](https://docs.microsoft.com/en-us/windows/apps/design/style/segoe-fluent-icons-font).
2022-07-14 06:35:16 -05:00
James Holderness
9ae68cca1e Add support for soft fonts in the DX renderer (#13362)
## Summary of the Pull Request

This PR adds support for downloadable soft fonts in the DirectX
renderer, potentially enabling them to be used in Windows Terminal.

## References

Soft fonts were first implemented in conhost (with the GDI renderer) in
PR #10011.

## PR Checklist
* [ ] Closes #xxx
* [x] CLA signed.
* [ ] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [ ] I've discussed this with core contributors already. If not
checked, I'm ready to accept this work might be rejected in favor of a
different grand plan. Issue number where discussion took place: #xxx

## Detailed Description of the Pull Request / Additional comments

The way the DirectX implementation works is by building up a bitmap
containing all of the glyphs, and then drawing an appropriate subsection
of that bitmap for each character that needs to be rendered. The current
text color is applied with a color matrix effect, and the glyphs are
automatically scaled up to the current font size with a scaling effect.

By default the scaling uses a high quality cubic interpolation, which
gives it a smoother antialiased effect. But if the *Text antialiasing*
option is configured as *Aliased*, we use a simpler nearest-neighbor
interpolation, which more closely matches the rendering of the original
GDI implementation.

## Validation Steps Performed

I've manually tested the renderer in conhost with the `UseDx` registry
entry. I've also tested in Windows Terminal using the experimental
passthrough mode.
2022-07-14 11:34:46 +00:00
James Holderness
bc79867b38 Reimplement DECPS using DirectSound in place of MIDI (#13471)
## Summary of the Pull Request

The original `DECPS` implementation made use of the Windows MIDI APIs to
generate the sound, but that required a 3MB package dependency for the
GS wavetable DLS. This PR reimplements the `MidiAudio` class using
`DirectSound`, so we can avoid that dependency.

## References

The original `DECPS` implementation was added in PR #13208, but was
hidden behind a velocity flag in #13258.

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

## Detailed Description of the Pull Request / Additional comments

The way it works is by creating a sound buffer with a single triangle
wave that is played in a loop. We generate different notes simply by
adjusting the frequency at which that buffer is played.

When we need a note to end, we just set the volume to its minimum value
rather than stopping the buffer. If we don't do that, the repeated
starting and stopping tends to produce a lot of static in the output. We
also use two buffers, which we alternate between notes, as another way
to reduce that static.

One other thing worth mentioning is the handling of the buffer position.
At the end of each note we save the current position, and then use an
offset from that position when starting the following note. This helps
produce a clearer separation between tones when repeating sequences of
the same note.

In an ideal world, we should really have something like an attack-decay-
sustain-release envelope for each note, but the above hack seems to work
reasonably well, and keeps the implementation simple.

## Validation Steps Performed

I've manually tested both conhost and Terminal with the sample tunes
listed in issue #8687, as well as a couple of games that I have which
make use of `DECPS` sound effects.
2022-07-14 11:33:59 +00:00
Davide Giacometti
56016c92f7 Setting for hide window when it loses focus (#13478)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
Added setting for for hide window when it loses focus.
Works on normal window and quake window.

<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> 
## References

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes #10660
* [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

<!-- 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

- Enable **Settings > Appearance > Automatically hide window**
- Terminal window should be minimized on taskbar when it loses focus
- Quake window should be minimized on system tray when it loses focus
- Enable also **Settings > Appearance > Hide Terminal in the notification area when it is minimized**
- Terminal window should be minimized on system tray when it loses focus
- Quake window should be minimized on system tray when it loses focus
2022-07-14 11:32:54 +00:00
Mike Griese
dc161d8018 Draft spec for theming, Mica (#12530)
⚠️ This spec is going into the `specs/drafts/` folder, because it's CLEARLY not done yet.

I discussed this a bit with Dustin. We felt it would be valuable to have these thoughts committed as a durable artifact. Better to have our Mica thoughts written down somewhere, with the context they belong in. That of course includes the bigger Theming spec, which never got finished. 

I don't think we need to go through the fill spec review for this. Theming is clearly still a WIP. But committing this draft should give a better picture of what the vision is. 

See also: 
* #3327
* #10509

### TODOs
* [ ] The many that are straight up in the doc
* [ ] The fact that there's multiple Mica's now
* [ ] GO look at MSFT:39027976
2022-07-14 06:05:37 -05:00
Dustin L. Howett
ae9532fb41 Fix PGO by "installing" a newer version of VCLibs to our app folder (#13502)
Moving to VS 2022 and C++20 in #13368 introduced a new dependency on an
as-yet-nonexistent VC Runtime library: msvcp140_atomic_wait.dll. That
library is not installed on the 21H1 machines that run our PGO tests.

Fortunately, the app platform will--largely--handle this dependency for
us on machines in the wild.

Fixes #13500
2022-07-14 03:28:18 +00:00
Dustin L. Howett
574a72b505 Port our Daily Loc Submission build out of Azure DevOps to YAML (#13492)
Does what it says on the tin!
2022-07-13 14:27:01 +00:00
Dustin L. Howett
5f3222b993 Stop our release pipeline from downloading the entire SDK *twice* (#13491)
The debugging tools folks helpfully published PdbStr and SrcTool as
NuGet packages for us to take a dependency on! Now we can end this
wasteful practice once and for all...

NOTE: This change introduces a harmless error message at the end of
symbol indexing. Instead of printing out the list of mapped sources,
`srctool` will complain that `srcsrv.dll` is missing. This is only cosmetic.
2022-07-13 14:26:05 +00:00
297 changed files with 6395 additions and 3759 deletions

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,7 +1,7 @@
admins
allcolors
apc
Apc
apc
breadcrumb
breadcrumbs
bsd
@@ -14,8 +14,8 @@ CMMI
copyable
cybersecurity
dalet
dcs
Dcs
dcs
dialytika
dje
downside
@@ -34,10 +34,12 @@ gantt
gcc
geeksforgeeks
ghe
github
gje
godbolt
hostname
hostnames
https
hyperlink
hyperlinking
hyperlinks
@@ -54,9 +56,11 @@ Llast
llvm
Lmid
locl
lol
lorem
Lorigin
maxed
minimalistic
mkmk
mnt
mru
@@ -80,6 +84,7 @@ runtimes
shcha
slnt
Sos
ssh
timeline
timelines
timestamped
@@ -88,6 +93,7 @@ tokenizes
tonos
toolset
tshe
ubuntu
uiatextrange
UIs
und
@@ -96,5 +102,7 @@ versioned
vsdevcmd
We'd
wildcards
XBox
YBox
yeru
zhe

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,11 +30,14 @@ dataobject
dcomp
DERR
dlldata
DNE
DONTADDTORECENT
DWORDLONG
DWMSBT
DWMWA
DWMWA
DWORDLONG
endfor
ENDSESSION
enumset
environstrings
EXPCMDFLAGS
@@ -72,6 +77,7 @@ IDirect
IExplorer
IFACEMETHOD
IFile
IGraphics
IInheritable
IMap
IMonarch
@@ -86,6 +92,7 @@ istream
IStringable
ITab
ITaskbar
itow
IUri
IVirtual
KEYSELECT
@@ -97,13 +104,14 @@ lround
Lsa
lsass
LSHIFT
LTGRAY
MAINWINDOW
memchr
memicmp
MENUCOMMAND
MENUDATA
MENUITEMINFOW
MENUINFO
MENUITEMINFOW
mmeapi
MOUSELEAVE
mov
@@ -140,16 +148,18 @@ OUTLINETEXTMETRICW
overridable
PACL
PAGESCROLL
PATINVERT
PEXPLICIT
PICKFOLDERS
pmr
ptstr
QUERYENDSESSION
rcx
REGCLS
RETURNCMD
rfind
roundf
ROOTOWNER
roundf
RSHIFT
SACL
schandle
@@ -200,6 +210,8 @@ UOI
UPDATEINIFILE
userenv
USEROBJECTFLAGS
Viewbox
virtualalloc
wcsstr
wcstoui
winmain

View File

@@ -69,6 +69,8 @@ Rincewind
rprichard
Schoonover
shadertoy
Shomnipotence
simioni
Somuah
sonph
sonpham

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,52 @@ 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/
@@ -78,7 +113,5 @@ SUMS$
^src/tools/U8U16Test/(?:fr|ru|zh)\.txt$
^src/types/ut_types/UtilsTests.cpp$
^tools/ReleaseEngineering/ServicingPipeline.ps1$
^\.github/actions/spelling/
^\.github/fabricbot.json$
^\.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,3 +1,5 @@
# 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)
@@ -21,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

@@ -11,9 +11,9 @@ Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "CascadiaPackage", "src\casc
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Host.EXE", "src\host\exe\Host.EXE.vcxproj", "{9CBD7DFA-1754-4A9D-93D7-857A9D17CB1B}"
ProjectSection(ProjectDependencies) = postProject
{71CC9D78-BA29-4D93-946F-BEF5D9A3A6EF} = {71CC9D78-BA29-4D93-946F-BEF5D9A3A6EF}
{0CF235BD-2DA0-407E-90EE-C467E8BBC714} = {0CF235BD-2DA0-407E-90EE-C467E8BBC714}
{5D23E8E1-3C64-4CC1-A8F7-6861677F7239} = {5D23E8E1-3C64-4CC1-A8F7-6861677F7239}
{71CC9D78-BA29-4D93-946F-BEF5D9A3A6EF} = {71CC9D78-BA29-4D93-946F-BEF5D9A3A6EF}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PropertiesLibrary", "src\propslib\propslib.vcxproj", "{345FD5A4-B32B-4F29-BD1C-B033BD2C35CC}"
@@ -64,9 +64,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RendererGdi", "src\renderer
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Host", "src\host\lib\hostlib.vcxproj", "{06EC74CB-9A12-429C-B551-8562EC954746}"
ProjectSection(ProjectDependencies) = postProject
{0CF235BD-2DA0-407E-90EE-C467E8BBC714} = {0CF235BD-2DA0-407E-90EE-C467E8BBC714}
{18D09A24-8240-42D6-8CB6-236EEE820263} = {18D09A24-8240-42D6-8CB6-236EEE820263}
{71CC9D78-BA29-4D93-946F-BEF5D9A3A6EF} = {71CC9D78-BA29-4D93-946F-BEF5D9A3A6EF}
{0CF235BD-2DA0-407E-90EE-C467E8BBC714} = {0CF235BD-2DA0-407E-90EE-C467E8BBC714}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Host.unittest", "src\host\ut_lib\host.unittest.vcxproj", "{06EC74CB-9A12-429C-B551-8562EC954747}"
@@ -77,8 +77,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Host.unittest", "src\host\u
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Host.Tests.Unit", "src\host\ut_host\Host.UnitTests.vcxproj", "{531C23E7-4B76-4C08-8AAD-04164CB628C9}"
ProjectSection(ProjectDependencies) = postProject
{0CF235BD-2DA0-407E-90EE-C467E8BBC714} = {0CF235BD-2DA0-407E-90EE-C467E8BBC714}
{06EC74CB-9A12-429C-B551-8562EC954747} = {06EC74CB-9A12-429C-B551-8562EC954747}
{0CF235BD-2DA0-407E-90EE-C467E8BBC714} = {0CF235BD-2DA0-407E-90EE-C467E8BBC714}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TextBuffer.Unit.Tests", "src\buffer\out\ut_textbuffer\TextBuffer.Unit.Tests.vcxproj", "{531C23E7-4B76-4C08-8BBD-04164CB628C9}"
@@ -89,9 +89,9 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Host.Tests.Feature", "src\host\ft_host\Host.FeatureTests.vcxproj", "{8CDB8850-7484-4EC7-B45B-181F85B2EE54}"
ProjectSection(ProjectDependencies) = postProject
{18D09A24-8240-42D6-8CB6-236EEE820263} = {18D09A24-8240-42D6-8CB6-236EEE820263}
{FC802440-AD6A-4919-8F2C-7701F2B38D79} = {FC802440-AD6A-4919-8F2C-7701F2B38D79}
{58A03BB2-DF5A-4B66-91A0-7EF3BA01269A} = {58A03BB2-DF5A-4B66-91A0-7EF3BA01269A}
{9CBD7DFA-1754-4A9D-93D7-857A9D17CB1B} = {9CBD7DFA-1754-4A9D-93D7-857A9D17CB1B}
{FC802440-AD6A-4919-8F2C-7701F2B38D79} = {FC802440-AD6A-4919-8F2C-7701F2B38D79}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalParser.UnitTests", "src\terminal\parser\ut_parser\Parser.UnitTests.vcxproj", "{12144E07-FE63-4D33-9231-748B8D8C3792}"
@@ -114,8 +114,8 @@ EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Host.Tests.UIA", "src\host\ft_uia\Host.Tests.UIA.csproj", "{C17E1BF3-9D34-4779-9458-A8EF98CC5662}"
ProjectSection(ProjectDependencies) = postProject
{099193A0-1E43-4BBC-BA7F-7B351E1342DF} = {099193A0-1E43-4BBC-BA7F-7B351E1342DF}
{C7A6A5D9-60BE-4AEB-A5F6-AFE352F86CBB} = {C7A6A5D9-60BE-4AEB-A5F6-AFE352F86CBB}
{9CBD7DFA-1754-4A9D-93D7-857A9D17CB1B} = {9CBD7DFA-1754-4A9D-93D7-857A9D17CB1B}
{C7A6A5D9-60BE-4AEB-A5F6-AFE352F86CBB} = {C7A6A5D9-60BE-4AEB-A5F6-AFE352F86CBB}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VTApp", "src\tools\vtapp\VTApp.csproj", "{099193A0-1E43-4BBC-BA7F-7B351E1342DF}"
@@ -172,12 +172,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalCore", "src\cascadi
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Terminal.Control.Lib", "src\cascadia\TerminalControl\TerminalControlLib.vcxproj", "{CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED}"
ProjectSection(ProjectDependencies) = postProject
{CA5CAD1A-C46D-4588-B1C0-40F31AE9100B} = {CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}
{CA5CAD1A-ABCD-429C-B551-8562EC954746} = {CA5CAD1A-ABCD-429C-B551-8562EC954746}
{1CF55140-EF6A-4736-A403-957E4F7430BB} = {1CF55140-EF6A-4736-A403-957E4F7430BB}
{48D21369-3D7B-4431-9967-24E81292CF62} = {48D21369-3D7B-4431-9967-24E81292CF62}
{48D21369-3D7B-4431-9967-24E81292CF63} = {48D21369-3D7B-4431-9967-24E81292CF63}
{8222900C-8B6C-452A-91AC-BE95DB04B95F} = {8222900C-8B6C-452A-91AC-BE95DB04B95F}
{AF0A096A-8B3A-4949-81EF-7DF8F0FEE91F} = {AF0A096A-8B3A-4949-81EF-7DF8F0FEE91F}
{CA5CAD1A-ABCD-429C-B551-8562EC954746} = {CA5CAD1A-ABCD-429C-B551-8562EC954746}
{CA5CAD1A-C46D-4588-B1C0-40F31AE9100B} = {CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Terminal.Control", "src\cascadia\TerminalControl\dll\TerminalControl.vcxproj", "{CA5CAD1A-F542-4635-A069-7CAEFB930070}"
@@ -187,21 +188,21 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Terminal.Control"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WindowsTerminal", "src\cascadia\WindowsTerminal\WindowsTerminal.vcxproj", "{CA5CAD1A-1754-4A9D-93D7-857A9D17CB1B}"
ProjectSection(ProjectDependencies) = postProject
{CA5CAD1A-F542-4635-A069-7CAEFB930070} = {CA5CAD1A-F542-4635-A069-7CAEFB930070}
{27B5AAEB-A548-44CF-9777-F8BAA32AF7AE} = {27B5AAEB-A548-44CF-9777-F8BAA32AF7AE}
{9CBD7DFA-1754-4A9D-93D7-857A9D17CB1B} = {9CBD7DFA-1754-4A9D-93D7-857A9D17CB1B}
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32} = {CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}
{CA5CAD1A-44BD-4AC7-AC72-F16E576FDD12} = {CA5CAD1A-44BD-4AC7-AC72-F16E576FDD12}
{CA5CAD1A-ABCD-429C-B551-8562EC954746} = {CA5CAD1A-ABCD-429C-B551-8562EC954746}
{27B5AAEB-A548-44CF-9777-F8BAA32AF7AE} = {27B5AAEB-A548-44CF-9777-F8BAA32AF7AE}
{9CBD7DFA-1754-4A9D-93D7-857A9D17CB1B} = {9CBD7DFA-1754-4A9D-93D7-857A9D17CB1B}
{CA5CAD1A-F542-4635-A069-7CAEFB930070} = {CA5CAD1A-F542-4635-A069-7CAEFB930070}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalApp", "src\cascadia\TerminalApp\dll\TerminalApp.vcxproj", "{CA5CAD1A-44BD-4AC7-AC72-F16E576FDD12}"
ProjectSection(ProjectDependencies) = postProject
{CA5CAD1A-9A12-429C-B551-8562EC954746} = {CA5CAD1A-9A12-429C-B551-8562EC954746}
{CA5CAD1A-082C-4476-9F33-94B339494076} = {CA5CAD1A-082C-4476-9F33-94B339494076}
{CA5CAD1A-F542-4635-A069-7CAEFB930070} = {CA5CAD1A-F542-4635-A069-7CAEFB930070}
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32} = {CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}
{CA5CAD1A-9A12-429C-B551-8562EC954746} = {CA5CAD1A-9A12-429C-B551-8562EC954746}
{CA5CAD1A-C46D-4588-B1C0-40F31AE9100B} = {CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}
{CA5CAD1A-F542-4635-A069-7CAEFB930070} = {CA5CAD1A-F542-4635-A069-7CAEFB930070}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WindowsTerminalShellExt", "src\cascadia\ShellExtension\WindowsTerminalShellExt.vcxproj", "{F2ED628A-DB22-446F-A081-4CC845B51A2B}"
@@ -251,15 +252,15 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalAppLib", "src\cascadia\TerminalApp\TerminalAppLib.vcxproj", "{CA5CAD1A-9A12-429C-B551-8562EC954746}"
ProjectSection(ProjectDependencies) = postProject
{CA5CAD1A-082C-4476-9F33-94B339494076} = {CA5CAD1A-082C-4476-9F33-94B339494076}
{CA5CAD1A-F542-4635-A069-7CAEFB930070} = {CA5CAD1A-F542-4635-A069-7CAEFB930070}
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32} = {CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}
{CA5CAD1A-F542-4635-A069-7CAEFB930070} = {CA5CAD1A-F542-4635-A069-7CAEFB930070}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LocalTests_TerminalApp", "src\cascadia\LocalTests_TerminalApp\TerminalApp.LocalTests.vcxproj", "{CA5CAD1A-B11C-4DDB-A4FE-C3AFAE9B5506}"
ProjectSection(ProjectDependencies) = postProject
{CA5CAD1A-9A12-429C-B551-8562EC954746} = {CA5CAD1A-9A12-429C-B551-8562EC954746}
{CA5CAD1A-082C-4476-9F33-94B339494076} = {CA5CAD1A-082C-4476-9F33-94B339494076}
{CA5CAD1A-44BD-4AC7-AC72-F16E576FDD12} = {CA5CAD1A-44BD-4AC7-AC72-F16E576FDD12}
{CA5CAD1A-9A12-429C-B551-8562EC954746} = {CA5CAD1A-9A12-429C-B551-8562EC954746}
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907} = {CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}
EndProjectSection
EndProject
@@ -273,9 +274,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winconpty.DLL", "src\wincon
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestHostApp", "src\cascadia\LocalTests_TerminalApp\TestHostApp\TestHostApp.vcxproj", "{A021EDFF-45C8-4DC2-BEF7-36E1B3B8CFE8}"
ProjectSection(ProjectDependencies) = postProject
{CA5CAD1A-B11C-4DDB-A4FE-C3AFAE9B5506} = {CA5CAD1A-B11C-4DDB-A4FE-C3AFAE9B5506}
{CA5CAD1A-082C-4476-9F33-94B339494076} = {CA5CAD1A-082C-4476-9F33-94B339494076}
{CA5CAD1A-9B68-456A-B13E-C8218070DC42} = {CA5CAD1A-9B68-456A-B13E-C8218070DC42}
{CA5CAD1A-B11C-4DDB-A4FE-C3AFAE9B5506} = {CA5CAD1A-B11C-4DDB-A4FE-C3AFAE9B5506}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{BDB237B6-1D1D-400F-84CC-40A58FA59C8E}"
@@ -330,8 +331,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fmt", "src\dep\fmt\fmt.vcxp
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WpfTerminalTestNetCore", "src\cascadia\WpfTerminalTestNetCore\WpfTerminalTestNetCore.csproj", "{1588FD7C-241E-4E7D-9113-43735F3E6BAD}"
ProjectSection(ProjectDependencies) = postProject
{A22EC5F6-7851-4B88-AC52-47249D437A52} = {A22EC5F6-7851-4B88-AC52-47249D437A52}
{84848BFA-931D-42CE-9ADF-01EE54DE7890} = {84848BFA-931D-42CE-9ADF-01EE54DE7890}
{A22EC5F6-7851-4B88-AC52-47249D437A52} = {A22EC5F6-7851-4B88-AC52-47249D437A52}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wt", "src\cascadia\wt\wt.vcxproj", "{506FD703-BAA7-4F6E-9361-64F550EC8FCA}"
@@ -356,9 +357,9 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LocalTests_SettingsModel", "src\cascadia\LocalTests_SettingsModel\SettingsModel.LocalTests.vcxproj", "{CA5CAD1A-9B68-456A-B13E-C8218070DC42}"
ProjectSection(ProjectDependencies) = postProject
{CA5CAD1A-082C-4476-9F33-94B339494076} = {CA5CAD1A-082C-4476-9F33-94B339494076}
{CA5CAD1A-F542-4635-A069-7CAEFB930070} = {CA5CAD1A-F542-4635-A069-7CAEFB930070}
{CA5CAD1A-C46D-4588-B1C0-40F31AE9100B} = {CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907} = {CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}
{CA5CAD1A-F542-4635-A069-7CAEFB930070} = {CA5CAD1A-F542-4635-A069-7CAEFB930070}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MonarchPeasantSample", "src\tools\MonarchPeasantSample\MonarchPeasantSample.vcxproj", "{21B7EA5E-1EF8-49B6-AC07-11714AF0E37D}"
@@ -377,8 +378,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Terminal.Remoting
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTests_Remoting", "src\cascadia\UnitTests_Remoting\Remoting.UnitTests.vcxproj", "{68A10CD3-AA64-465B-AF5F-ED4E9700543C}"
ProjectSection(ProjectDependencies) = postProject
{43CE4CE5-0010-4B99-9569-672670D26E26} = {43CE4CE5-0010-4B99-9569-672670D26E26}
{27B5AAEB-A548-44CF-9777-F8BAA32AF7AE} = {27B5AAEB-A548-44CF-9777-F8BAA32AF7AE}
{43CE4CE5-0010-4B99-9569-672670D26E26} = {43CE4CE5-0010-4B99-9569-672670D26E26}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "wpf", "wpf", "{4DAF0299-495E-4CD1-A982-9BAC16A45932}"
@@ -400,8 +401,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTests_Control", "src\ca
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsTerminal.UIA.Tests", "src\cascadia\WindowsTerminal_UIATests\WindowsTerminal.UIA.Tests.csproj", "{F19DACD5-0C6E-40DC-B6E4-767A3200542C}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "api-ms-win-core-synch-l1-2-0", "src\api-ms-win-core-synch-l1-2-0\api-ms-win-core-synch-l1-2-0.vcxproj", "{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Utils", "Utils", "{61901E80-E97D-4D61-A9BB-E8F2FDA8B40C}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RendererAtlas", "src\renderer\atlas\atlas.vcxproj", "{8222900C-8B6C-452A-91AC-BE95DB04B95F}"
@@ -3300,49 +3299,6 @@ Global
{F19DACD5-0C6E-40DC-B6E4-767A3200542C}.Release|x64.Build.0 = Release|x64
{F19DACD5-0C6E-40DC-B6E4-767A3200542C}.Release|x86.ActiveCfg = Release|Win32
{F19DACD5-0C6E-40DC-B6E4-767A3200542C}.Release|x86.Build.0 = Release|Win32
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.AuditMode|Any CPU.ActiveCfg = AuditMode|Win32
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.AuditMode|ARM.ActiveCfg = AuditMode|Win32
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.AuditMode|DotNet_x64Test.ActiveCfg = AuditMode|Win32
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.AuditMode|DotNet_x86Test.ActiveCfg = AuditMode|Win32
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.AuditMode|x64.ActiveCfg = AuditMode|x64
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.AuditMode|x64.Build.0 = AuditMode|x64
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.AuditMode|x86.ActiveCfg = AuditMode|Win32
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.AuditMode|x86.Build.0 = AuditMode|Win32
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Debug|Any CPU.ActiveCfg = Debug|Win32
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Debug|ARM.ActiveCfg = Debug|Win32
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Debug|ARM64.ActiveCfg = Debug|ARM64
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Debug|ARM64.Build.0 = Debug|ARM64
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Debug|DotNet_x64Test.ActiveCfg = Debug|x64
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Debug|DotNet_x64Test.Build.0 = Debug|x64
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Debug|DotNet_x86Test.ActiveCfg = Debug|Win32
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Debug|DotNet_x86Test.Build.0 = Debug|Win32
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Debug|x64.ActiveCfg = Debug|x64
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Debug|x64.Build.0 = Debug|x64
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Debug|x86.ActiveCfg = Debug|Win32
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Debug|x86.Build.0 = Debug|Win32
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|Win32
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Fuzzing|ARM.ActiveCfg = Fuzzing|Win32
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Fuzzing|ARM64.Build.0 = Fuzzing|ARM64
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Fuzzing|DotNet_x64Test.ActiveCfg = Fuzzing|Win32
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Fuzzing|DotNet_x86Test.ActiveCfg = Fuzzing|Win32
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Fuzzing|x64.ActiveCfg = Fuzzing|x64
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Fuzzing|x86.Build.0 = Fuzzing|Win32
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Release|Any CPU.ActiveCfg = Release|Win32
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Release|ARM.ActiveCfg = Release|Win32
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Release|ARM64.ActiveCfg = Release|ARM64
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Release|ARM64.Build.0 = Release|ARM64
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Release|DotNet_x64Test.ActiveCfg = Release|x64
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Release|DotNet_x64Test.Build.0 = Release|x64
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Release|DotNet_x86Test.ActiveCfg = Release|Win32
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Release|DotNet_x86Test.Build.0 = Release|Win32
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Release|x64.ActiveCfg = Release|x64
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Release|x64.Build.0 = Release|x64
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Release|x86.ActiveCfg = Release|Win32
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Release|x86.Build.0 = Release|Win32
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.AuditMode|Any CPU.ActiveCfg = AuditMode|Win32
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.AuditMode|ARM.ActiveCfg = AuditMode|Win32
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
@@ -3591,7 +3547,6 @@ Global
{05D9052F-D78F-478F-968A-2DE38A6DB996} = {E8F24881-5E37-4362-B191-A3BA0ED7F4EB}
{C323DAEE-B307-4C7B-ACE5-7293CBEFCB5B} = {BDB237B6-1D1D-400F-84CC-40A58FA59C8E}
{F19DACD5-0C6E-40DC-B6E4-767A3200542C} = {BDB237B6-1D1D-400F-84CC-40A58FA59C8E}
{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}

View File

@@ -21,7 +21,7 @@ Related repositories include:
## Installing and running Windows Terminal
> 🔴 Note: Windows Terminal requires Windows 10 2004 (build 19041) or later
> **Note**: Windows Terminal requires Windows 10 2004 (build 19041) or later
### Microsoft Store [Recommended]
@@ -52,8 +52,10 @@ fails for any reason, you can try the following command at a PowerShell prompt:
Add-AppxPackage Microsoft.WindowsTerminal_<versionNumber>.msixbundle
```
> 🔴 Note: If you install Terminal manually:
> **Note**: If you install Terminal manually:
>
> * You may need to install the [VC++ v14 Desktop Framework Package](https://docs.microsoft.com/troubleshoot/cpp/c-runtime-packages-desktop-bridge#how-to-install-and-update-desktop-framework-packages).
> This should only be necessary on older builds of Windows 10 and only if you get an error about missing framework packages.
> * Terminal will not auto-update when new builds are released so you will need
> to regularly install the latest Terminal release to receive all the latest
> fixes and improvements!
@@ -233,7 +235,7 @@ Cause: You're launching the incorrect solution in Visual Studio.
Solution: Make sure you're building & deploying the `CascadiaPackage` project in
Visual Studio.
> Note: `OpenConsole.exe` is just a locally-built `conhost.exe`, the classic
> **Note**: `OpenConsole.exe` is just a locally-built `conhost.exe`, the classic
> Windows Console that hosts Windows' command-line infrastructure. OpenConsole
> is used by Windows Terminal to connect to and communicate with command-line
> applications (via
@@ -264,7 +266,7 @@ help avoid any wasted or duplicate effort.
The easiest way to communicate with the team is via GitHub issues.
Please file new issues, feature requests and suggestions, but **DO search for
similar open/closed pre-existing issues before creating a new issue.**
similar open/closed preexisting issues before creating a new issue.**
If you would like to ask a question that you feel doesn't warrant an issue
(yet), please reach out to us via Twitter:

View File

@@ -55,8 +55,9 @@ Copy-Item "build\helix\runtests.cmd" $payloadDir
Copy-Item "build\helix\InstallTestAppDependencies.ps1" "$payloadDir"
Copy-Item "build\Helix\EnsureMachineState.ps1" "$payloadDir"
# Copy the APPX package from the 'drop' artifact dir
# Copy the APPX package from the 'drop' artifact dir and Windows Kits
Copy-Item "$repoDirectory\Artifacts\$ArtifactName\appx\CascadiaPackage_0.0.1.0_$Platform.msix" $payloadDir\CascadiaPackage.zip
Copy-Item "C:\program files (x86)\Microsoft SDKs\Windows Kits\10\ExtensionSDKs\Microsoft.VCLibs.Desktop\14.0\Appx\Retail\x64\Microsoft.VCLibs.x64.14.00.Desktop.appx" $payloadDir\VCLibs.zip
# Rename it to extension of ZIP because Expand-Archive is real sassy on the build machines
# and refuses to unzip it because of its file extension while on a desktop, it just
@@ -64,3 +65,4 @@ Copy-Item "$repoDirectory\Artifacts\$ArtifactName\appx\CascadiaPackage_0.0.1.0_$
# Extract the APPX package
Expand-Archive -LiteralPath $payloadDir\CascadiaPackage.zip -DestinationPath $payloadDir\appx
Expand-Archive -LiteralPath $payloadDir\VCLibs.zip -DestinationPath $payloadDir\appx -Force

View File

@@ -5,4 +5,6 @@
<package id="Microsoft.Internal.PGO-Helpers.Cpp" version="0.2.34" targetFramework="native" />
<!-- This cannot be included in another project that depends on XAML (as it would be a duplicate package ID) -->
<package id="Microsoft.UI.Xaml" version="2.7.0" targetFramework="native" />
<package id="Microsoft.Debugging.Tools.PdbStr" version="20220617.1556.0" targetFramework="native" />
<package id="Microsoft.Debugging.Tools.SrcTool" version="20220617.1556.0" targetFramework="native" />
</packages>

View File

@@ -1,4 +1,4 @@
<?xml version="1.0"?>
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Microsoft.Internal.Windows.Terminal.PGODatabase</id>

View File

@@ -0,0 +1,62 @@
trigger: none
pr: none
schedules:
- cron: "0 3 * * 2-6" # Run at 03:00 UTC Tuesday through Saturday (After the work day in Pacific, Mon-Fri)
displayName: "Nightly Localization Build"
branches:
include:
- main
always: false # only run if there's code changes!
pool:
vmImage: windows-2019
resources:
repositories:
- repository: self
type: git
ref: main
- repository: internal
type: git
name: Terminal.Internal
ref: main
steps:
- checkout: self
clean: true
submodules: false
fetchDepth: 1 # Don't need a deep checkout for loc files!
persistCredentials: true
path: s # Adding a second repo made Azure DevOps change where we're checked out.
- checkout: internal
clean: true
submodules: false
fetchDepth: 1
persistCredentials: true
path: s/Terminal.Internal
- task: MicrosoftTDBuild.tdbuild-task.tdbuild-task.TouchdownBuildTask@1
displayName: 'Touchdown Build - 7105, PRODEXT'
inputs:
teamId: 7105
authId: '$(TouchdownApplicationID)'
authKey: '$(TouchdownApplicationKey)'
resourceFilePath: |
**\en-US\*.resw
Terminal.Internal\PDPs\Stable\PDPs\en-us\PDP.xml
Terminal.Internal\PDPs\Preview\PDPs\en-us\PDP.xml
outputDirectoryRoot: LocOutput
appendRelativeDir: true
pseudoSetting: Included
# Saving one of these makes it really easy to inspect the loc output...
- powershell: 'tar czf LocOutput.tar.gz LocOutput'
displayName: 'Archive Loc Output for Submission'
- task: PublishBuildArtifacts@1
displayName: 'Publish Artifact: LocOutput'
inputs:
PathtoPublish: LocOutput.tar.gz
ArtifactName: LocOutput

View File

@@ -134,8 +134,6 @@ jobs:
Write-Host "##vso[task.setvariable variable=RationalizedBuildPlatform]${Arch}"
- template: .\templates\restore-nuget-steps.yml
# Pull the Windows SDK for the developer tools like the debuggers so we can index sources later
- template: .\templates\install-winsdk-steps.yml
- task: UniversalPackages@0
displayName: Download terminal-internal Universal Package
inputs:
@@ -238,6 +236,7 @@ jobs:
filePath: build\scripts\Index-Pdbs.ps1
arguments: -SearchDir '$(Build.SourcesDirectory)' -SourceRoot '$(Build.SourcesDirectory)' -recursive -Verbose -CommitId $(Build.SourceVersion)
errorActionPreference: silentlyContinue
pwsh: true
- task: PowerShell@2
displayName: Run Unit Tests
condition: and(succeeded(), or(eq(variables['BuildPlatform'], 'x64'), eq(variables['BuildPlatform'], 'x86')))
@@ -300,8 +299,6 @@ jobs:
inputs:
Contents: >-
**/PublicTerminalCore.dll
**/api-ms-win-core-synch-l1-2-0.dll
TargetFolder: $(Build.ArtifactStagingDirectory)/wpf
OverWrite: true
flattenFolders: true
@@ -608,6 +605,8 @@ jobs:
- task: PkgESSetupBuild@12
displayName: Package ES - Setup Build
- template: .\templates\restore-nuget-steps.yml
# Download the appx-PLATFORM-CONFIG-VERSION artifact for every platform/version combo
- ${{ each platform in parameters.buildPlatforms }}:
- ${{ each windowsVersion in parameters.buildWindowsVersions }}:
@@ -630,13 +629,12 @@ jobs:
}
displayName: Extract symbols for public consumption
# Pull the Windows SDK for the developer tools like the debuggers so we can index sources later
- template: .\templates\install-winsdk-steps.yml
- task: PowerShell@2
displayName: Source Index PDBs (the public ones)
inputs:
filePath: build\scripts\Index-Pdbs.ps1
arguments: -SearchDir '$(Build.SourcesDirectory)/appxsym-temp' -SourceRoot '$(Build.SourcesDirectory)' -recursive -Verbose -CommitId $(Build.SourceVersion)
pwsh: true
# Publish the app symbols to the public MSDL symbol server
# accessible via https://msdl.microsoft.com/download/symbols

View File

@@ -71,7 +71,7 @@ jobs:
# 1ES Component Governance onboarding (Detects open source components). See https://docs.opensource.microsoft.com/tools/cg.html
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
displayName: Component Detection
# # PREfast and PoliCheck need Node. Install that first.
- task: NodeTool@0
@@ -82,7 +82,7 @@ jobs:
# step instead that builds the code normally before calling them.
# Also... PREfast will rebuild anyway so that's why we're not running a normal build first.
# Waste of time to build twice.
# PREfast. See https://www.1eswiki.com/wiki/SDL_Native_Rules_Build_Task
# PREfast. See https://www.1eswiki.com/wiki/SDL_Native_Rules_Build_Task
# The following 1ES tasks all operate completely differently and have a different syntax for usage.
# Most notable is every one of them has a different way of excluding things.
@@ -98,7 +98,9 @@ jobs:
displayName: 'Run the PREfast SDL Native Rules for MSBuild'
condition: succeededOrFailed()
inputs:
msBuildCommandline: msbuild.exe /nologo /m /p:WindowsTerminalOfficialBuild=true /p:WindowsTerminalBranding=${{ parameters.branding }} /p:WindowsTerminalReleaseBuild=true /p:platform=$(BuildPlatform) /p:configuration=$(BuildConfiguration) /t:Terminal\Window\WindowsTerminal /p:VisualStudioVersion=16.0 $(Build.SourcesDirectory)\OpenConsole.sln
setupCommandlines: '"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsMSBuildCmd.bat"'
msBuildCommandline: msbuild.exe /nologo /m /p:WindowsTerminalOfficialBuild=true /p:WindowsTerminalBranding=${{ parameters.branding }} /p:WindowsTerminalReleaseBuild=true /p:platform=$(BuildPlatform) /p:configuration=$(BuildConfiguration) /t:Terminal\Window\WindowsTerminal /p:VisualStudioVersion=17.0 $(Build.SourcesDirectory)\OpenConsole.sln
msBuildVersion: "17.0"
# Copies output from PREfast SDL Native Rules task to expected location for consumption by PkgESSecComp
- task: CopyFiles@1
@@ -146,7 +148,7 @@ jobs:
continueOnError: true
# Set XES_SERIALPOSTBUILDREADY to run Security and Compliance task once per build
- powershell: Write-Host ##vso[task.setvariable variable=XES_SERIALPOSTBUILDREADY;]true
- powershell: Write-Host "##vso[task.setvariable variable=XES_SERIALPOSTBUILDREADY;]true"
displayName: 'Set XES_SERIALPOSTBUILDREADY Vars'
# https://www.osgwiki.com/wiki/Package_ES_Security_and_Compliance
@@ -156,12 +158,12 @@ jobs:
# (PREfast, PoliCheck, Credscan)
# - Runs Windows-specific compliance tasks inside the task
# + CheckCFlags - ensures that compiler and linker flags meet Windows standards
# + CFGCheck/XFGCheck - ensures that Control Flow Guard (CFG) or
# + CFGCheck/XFGCheck - ensures that Control Flow Guard (CFG) or
# eXtended Flow Guard (XFG) are enabled on binaries
# NOTE: CFG is deprecated and XFG isn't fully ready yet.
# NOTE2: CFG fails on an XFG'd binary
# - Brokers all security/compliance task logs to "Trust Services Automation (TSA)" (https://aka.ms/tsa)
# which is a system that maps all errors into the appropriate bug database
# which is a system that maps all errors into the appropriate bug database
# template for each organization since they all vary. It should also suppress
# new bugs when one already exists for the product.
# This one is set up to go to the OS repository and use the given parameters
@@ -198,4 +200,4 @@ jobs:
- toolName: CredScan
enable: false
- toolName: XFGCheck
enable: false
enable: false

View File

@@ -1,9 +0,0 @@
parameters:
sdkVersion: 18362
steps:
- task: powershell@2
inputs:
targetType: filePath
filePath: build\scripts\Install-WindowsSdkISO.ps1
arguments: ${{ parameters.sdkVersion }}
displayName: 'Install Windows SDK (${{ parameters.sdkVersion }})'

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<_WTBrandingPreprocessorToken Condition="'$(WindowsTerminalBranding)'=='Preview'">WT_BRANDING_PREVIEW</_WTBrandingPreprocessorToken>
<_WTBrandingPreprocessorToken Condition="'$(WindowsTerminalBranding)'=='Release'">WT_BRANDING_RELEASE</_WTBrandingPreprocessorToken>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
</PropertyGroup>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- THIS PROJECT CANNOT BE LOADED INTO THE SOLUTION. -->
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<BeforeLinkTargets Condition="'$(WindowsTargetPlatformVersion)' &gt;= '10.0.18362.0'">
$(BeforeLinkTargets);

View File

@@ -8,10 +8,11 @@ Param(
[switch]$recursive
)
$debuggerPath = (Get-ItemProperty -path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Kits\Installed Roots" -name WindowsDebuggersRoot10).WindowsDebuggersRoot10
$srcsrvPath = Join-Path $debuggerPath "x64\srcsrv"
$srctoolExe = Join-Path $srcsrvPath "srctool.exe"
$pdbstrExe = Join-Path $srcsrvPath "pdbstr.exe"
$pdbStrPackage = ([xml](Get-Content "$SourceRoot\build\packages.config")).packages.package | Where-Object id -like "*PdbStr*"
# This assumes that we rev PdbStr and SrcTool at the same time.
$debugPackageVersions = $pdbStrPackage.version
$srctoolExe = Join-Path $SourceRoot "packages" "Microsoft.Debugging.Tools.SrcTool.$debugPackageVersions" "content" "amd64" "srctool.exe"
$pdbstrExe = Join-Path $SourceRoot "packages" "Microsoft.Debugging.Tools.PdbStr.$debugPackageVersions" "content" "amd64" "pdbstr.exe"
$fileTable = @{}
foreach ($gitFile in & git ls-files)

View File

@@ -1,346 +0,0 @@
[CmdletBinding()]
param([Parameter(Mandatory=$true, Position=0)]
[string]$buildNumber)
# Ensure the error action preference is set to the default for PowerShell3, 'Stop'
$ErrorActionPreference = 'Stop'
# Constants
$WindowsSDKOptions = @("OptionId.UWPCpp", "OptionId.DesktopCPPx64", "OptionId.DesktopCPPx86", "OptionId.DesktopCPPARM64", "OptionId.DesktopCPPARM", "OptionId.WindowsDesktopDebuggers")
$WindowsSDKRegPath = "HKLM:\Software\WOW6432Node\Microsoft\Windows Kits\Installed Roots"
$WindowsSDKRegRootKey = "KitsRoot10"
$WindowsSDKVersion = "10.0.$buildNumber.0"
$WindowsSDKInstalledRegPath = "$WindowsSDKRegPath\$WindowsSDKVersion\Installed Options"
$StrongNameRegPath = "HKLM:\SOFTWARE\Microsoft\StrongName\Verification"
$PublicKeyTokens = @("31bf3856ad364e35")
if ($buildNumber -notmatch "^\d{5,}$")
{
Write-Host "ERROR: '$buildNumber' doesn't look like a windows build number"
Write-Host
Exit 1
}
function Download-File
{
param ([string] $outDir,
[string] $downloadUrl,
[string] $downloadName)
$downloadPath = Join-Path $outDir "$downloadName.download"
$downloadDest = Join-Path $outDir $downloadName
$downloadDestTemp = Join-Path $outDir "$downloadName.tmp"
Write-Host -NoNewline "Downloading $downloadName..."
$retries = 10
$downloaded = $false
while (-not $downloaded)
{
try
{
$webclient = new-object System.Net.WebClient
$webclient.DownloadFile($downloadUrl, $downloadPath)
$downloaded = $true
}
catch [System.Net.WebException]
{
Write-Host
Write-Warning "Failed to fetch updated file from $downloadUrl : $($error[0])"
if (!(Test-Path $downloadDest))
{
if ($retries -gt 0)
{
Write-Host "$retries retries left, trying download again"
$retries--
start-sleep -Seconds 10
}
else
{
throw "$downloadName was not found at $downloadDest"
}
}
else
{
Write-Warning "$downloadName may be out of date"
}
}
}
Unblock-File $downloadPath
$downloadDestTemp = $downloadPath;
# Delete and rename to final dest
Write-Host "testing $downloadDest"
if (Test-Path $downloadDest)
{
Write-Host "Deleting: $downloadDest"
Remove-Item $downloadDest -Force
}
Move-Item -Force $downloadDestTemp $downloadDest
Write-Host "Done"
return $downloadDest
}
function Get-ISODriveLetter
{
param ([string] $isoPath)
$diskImage = Get-DiskImage -ImagePath $isoPath
if ($diskImage)
{
$volume = Get-Volume -DiskImage $diskImage
if ($volume)
{
$driveLetter = $volume.DriveLetter
if ($driveLetter)
{
$driveLetter += ":"
return $driveLetter
}
}
}
return $null
}
function Mount-ISO
{
param ([string] $isoPath)
# Check if image is already mounted
$isoDrive = Get-ISODriveLetter $isoPath
if (!$isoDrive)
{
Mount-DiskImage -ImagePath $isoPath -StorageType ISO | Out-Null
}
$isoDrive = Get-ISODriveLetter $isoPath
Write-Verbose "$isoPath mounted to ${isoDrive}:"
}
function Dismount-ISO
{
param ([string] $isoPath)
$isoDrive = (Get-DiskImage -ImagePath $isoPath | Get-Volume).DriveLetter
if ($isoDrive)
{
Write-Verbose "$isoPath dismounted"
Dismount-DiskImage -ImagePath $isoPath | Out-Null
}
}
function Disable-StrongName
{
param ([string] $publicKeyToken = "*")
reg ADD "HKLM\SOFTWARE\Microsoft\StrongName\Verification\*,$publicKeyToken" /f | Out-Null
if ($env:PROCESSOR_ARCHITECTURE -eq "AMD64")
{
reg ADD "HKLM\SOFTWARE\Wow6432Node\Microsoft\StrongName\Verification\*,$publicKeyToken" /f | Out-Null
}
}
function Test-Admin
{
$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = New-Object Security.Principal.WindowsPrincipal $identity
$principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
function Test-RegistryPathAndValue
{
param (
[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string] $path,
[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string] $value)
try
{
if (Test-Path $path)
{
Get-ItemProperty -Path $path | Select-Object -ExpandProperty $value -ErrorAction Stop | Out-Null
return $true
}
}
catch
{
}
return $false
}
function Test-InstallWindowsSDK
{
$retval = $true
if (Test-RegistryPathAndValue -Path $WindowsSDKRegPath -Value $WindowsSDKRegRootKey)
{
# A Windows SDK is installed
# Is an SDK of our version installed with the options we need?
$allRequiredSdkOptionsInstalled = $true
foreach($sdkOption in $WindowsSDKOptions)
{
if (!(Test-RegistryPathAndValue -Path $WindowsSDKInstalledRegPath -Value $sdkOption))
{
$allRequiredSdkOptionsInstalled = $false
}
}
if($allRequiredSdkOptionsInstalled)
{
# It appears we have what we need. Double check the disk
$sdkRoot = Get-ItemProperty -Path $WindowsSDKRegPath | Select-Object -ExpandProperty $WindowsSDKRegRootKey
if ($sdkRoot)
{
if (Test-Path $sdkRoot)
{
$refPath = Join-Path $sdkRoot "References\$WindowsSDKVersion"
if (Test-Path $refPath)
{
$umdPath = Join-Path $sdkRoot "UnionMetadata\$WindowsSDKVersion"
if (Test-Path $umdPath)
{
# Pretty sure we have what we need
$retval = $false
}
}
}
}
}
}
return $retval
}
function Test-InstallStrongNameHijack
{
foreach($publicKeyToken in $PublicKeyTokens)
{
$key = "$StrongNameRegPath\*,$publicKeyToken"
if (!(Test-Path $key))
{
return $true
}
}
return $false
}
Write-Host -NoNewline "Checking for installed Windows SDK $WindowsSDKVersion..."
$InstallWindowsSDK = Test-InstallWindowsSDK
if ($InstallWindowsSDK)
{
Write-Host "Installation required"
}
else
{
Write-Host "INSTALLED"
}
$StrongNameHijack = Test-InstallStrongNameHijack
Write-Host -NoNewline "Checking if StrongName bypass required..."
if ($StrongNameHijack)
{
Write-Host "REQUIRED"
}
else
{
Write-Host "Done"
}
if ($StrongNameHijack -or $InstallWindowsSDK)
{
if (!(Test-Admin))
{
Write-Host
throw "ERROR: Elevation required"
}
}
if ($InstallWindowsSDK)
{
# Static(ish) link for Windows SDK
# Note: there is a delay from Windows SDK announcements to availability via the static link
$uri = "https://software-download.microsoft.com/download/sg/Windows_InsiderPreview_SDK_en-us_$($buildNumber)_1.iso";
if ($env:TEMP -eq $null)
{
$env:TEMP = Join-Path $env:SystemDrive 'temp'
}
$winsdkTempDir = Join-Path (Join-Path $env:TEMP ([System.IO.Path]::GetRandomFileName())) "WindowsSDK"
if (![System.IO.Directory]::Exists($winsdkTempDir))
{
[void][System.IO.Directory]::CreateDirectory($winsdkTempDir)
}
$file = "winsdk_$buildNumber.iso"
Write-Verbose "Getting WinSDK from $uri"
$downloadFile = Download-File $winsdkTempDir $uri $file
Write-Verbose "File is at $downloadFile"
$downloadFileItem = Get-Item $downloadFile
# Check to make sure the file is at least 10 MB.
if ($downloadFileItem.Length -lt 10*1024*1024)
{
Write-Host
Write-Host "ERROR: Downloaded file doesn't look large enough to be an ISO. The requested version may not be on microsoft.com yet."
Write-Host
Exit 1
}
# TODO Check if zip, exe, iso, etc.
try
{
Write-Host -NoNewline "Mounting ISO $file..."
Mount-ISO $downloadFile
Write-Host "Done"
$isoDrive = Get-ISODriveLetter $downloadFile
if (Test-Path $isoDrive)
{
Write-Host -NoNewLine "Installing WinSDK..."
$setupPath = Join-Path "$isoDrive" "WinSDKSetup.exe"
Start-Process -Wait $setupPath "/features $WindowsSDKOptions /q"
Write-Host "Done"
}
else
{
throw "Could not find mounted ISO at ${isoDrive}"
}
}
finally
{
Write-Host -NoNewline "Dismounting ISO $file..."
Dismount-ISO $downloadFile
Write-Host "Done"
}
}
if ($StrongNameHijack)
{
Write-Host -NoNewline "Disabling StrongName for Windows SDK..."
foreach($key in $PublicKeyTokens)
{
Disable-StrongName $key
}
Write-Host "Done"
}

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!--
This props file is a workaround for the fact that for wapproj projects,

View File

@@ -26,7 +26,6 @@
"/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/",

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- This file is read by XES, which we use in our Release builds. -->
<PropertyGroup Label="Version">
<!--

View File

@@ -139,3 +139,18 @@ powershell -Command Set-Location -Path %OPENCON%\src\cascadia\CascadiaPackage\Ap
(yes, the cmd version is just calling powershell to do the powershell version. Too lazy to convert the rest by hand, I'm already copying from `.vscode\tasks.json`)
Building the package from VS generates the loose layout to begin with, and then registers the loose manifest, skipping the msix stop. It's a lot faster than the commandline inner loop here, unfortunately.
### 2022 Update
The following command can be used to build the terminal package, and then deploy it.
```cmd
pushd %OPENCON%\src\cascadia\CascadiaPackage
bx
"C:\Program Files\Microsoft Visual Studio\2022\Preview\Common7\IDE\DeployAppRecipe.exe" bin\%ARCH%\%_LAST_BUILD_CONF%\CascadiaPackage.build.appxrecipe
popd
```
The `bx` will build just the Terminal package, critically, populating the `CascadiaPackage.build.appxrecipe` file. Once that's been built, then the `DeployAppRecipe.exe` command can be used to deploy a loose layout in the same way that Visual Studio does.
Notably, this method of building the Terminal package can't leverage the FastUpToDate check in Visual Studio, so the builds end up being considerably slower for the whole package, as cppwinrt does a lot of work before confirming that it's up to date and doing nothing.

View File

@@ -207,8 +207,14 @@
"type": "string"
},
"adjustIndistinguishableColors": {
"description": "When set to true, we will (when necessary) adjust the foreground color to make it more visible, based on the background color.",
"type": "boolean"
"default": "never",
"description": "Setting to adjust the foreground color to make it more visible, based on the background color. When set to \"indexed\", we will only adjust the colors if they came from the color scheme. Other possible values are \"never\" and \"always\".",
"enum": [
"never",
"indexed",
"always"
],
"type": "string"
},
"experimental.retroTerminalEffect": {
"description": "When set to true, enable retro terminal effects when unfocused. This is an experimental feature, and its continued existence is not guaranteed.",
@@ -1727,16 +1733,6 @@
"description": "When set to true, URLs will be detected by the Terminal. This will cause URLs to underline on hover and be clickable by pressing Ctrl.",
"type": "boolean"
},
"experimental.autoMarkPrompts": {
"default": false,
"description": "When set to true, prompts will automatically be marked.",
"type": "boolean"
},
"experimental.showMarksOnScrollbar": {
"default": false,
"description": "When set to true, marks added to the buffer via the addMark action will appear on the scrollbar.",
"type": "boolean"
},
"disableAnimations": {
"default": false,
"description": "When set to `true`, visual animations will be disabled across the application.",
@@ -1968,6 +1964,20 @@
"useAnyExisting"
],
"type": "string"
},
"newTabPosition": {
"default": "afterLastTab",
"description": "Position of newly created tabs. Possible values are \"afterLastTab\" and \"afterCurrentTab\".",
"enum": [
"afterLastTab",
"afterCurrentTab"
],
"type": "string"
},
"autoHideWindow": {
"default": false,
"description": "If enabled, Terminal window will be hidden as soon as it loses focus.",
"type": "boolean"
}
},
"required": [
@@ -2086,14 +2096,15 @@
"$ref": "#/$defs/BellSound"
},
"closeOnExit": {
"default": "graceful",
"description": "Sets how the profile reacts to termination or failure to launch. Possible values:\n -\"graceful\" (close when exit is typed or the process exits normally)\n -\"always\" (always close)\n -\"never\" (never close).\ntrue and false are accepted as synonyms for \"graceful\" and \"never\" respectively.",
"default": "automatic",
"description": "Sets how the profile reacts to termination or failure to launch. Possible values:\n -\"graceful\" (close when exit is typed or the process exits normally)\n -\"always\" (always close)\n -\"automatic\" (behave as \"graceful\" only for processes launched by terminal, behave as \"always\" otherwise)\n -\"never\" (never close).\ntrue and false are accepted as synonyms for \"graceful\" and \"never\" respectively.",
"oneOf": [
{
"enum": [
"never",
"graceful",
"always"
"always",
"automatic"
],
"type": "string"
},
@@ -2150,6 +2161,11 @@
"default": false,
"description": "When true, this profile should always open in an elevated context. If the window isn't running as an Administrator, then a new elevated window will be created."
},
"experimental.autoMarkPrompts": {
"default": false,
"description": "When set to true, prompts will automatically be marked.",
"type": "boolean"
},
"experimental.connection.passthroughMode": {
"description": "When set to true, directs the PTY for this connection to use pass-through mode instead of the original Conhost PTY simulation engine. This is an experimental feature, and its continued existence is not guaranteed.",
"type": "boolean"
@@ -2158,6 +2174,11 @@
"description": "When set to true, enable retro terminal effects. This is an experimental feature, and its continued existence is not guaranteed.",
"type": "boolean"
},
"experimental.showMarksOnScrollbar": {
"default": false,
"description": "When set to true, marks added to the buffer via the addMark action will appear on the scrollbar.",
"type": "boolean"
},
"experimental.pixelShaderPath": {
"description": "Use to set a path to a pixel shader to use with the Terminal. Overrides `experimental.retroTerminalEffect`. This is an experimental feature, and its continued existence is not guaranteed.",
"type": "string"
@@ -2261,8 +2282,14 @@
]
},
"adjustIndistinguishableColors": {
"description": "When set to true, we will (when necessary) adjust the foreground color to make it more visible, based on the background color.",
"type": "boolean"
"default": "never",
"description": "Setting to adjust the foreground color to make it more visible, based on the background color. When set to \"indexed\", we will only adjust the colors if they came from the color scheme. Other possible values are \"never\" and \"always\".",
"enum": [
"never",
"indexed",
"always"
],
"type": "string"
},
"scrollbarState": {
"default": "visible",

View File

@@ -5,7 +5,7 @@ Feature flags are controlled by an XML document stored at `src/features.xml`.
## Example Document
```xml
<?xml version="1.0"?>
<?xml version="1.0" encoding="utf-8"?>
<featureStaging xmlns="http://microsoft.com/TilFeatureStaging-Schema.xsd">
<feature>
<!-- This will produce Feature_XYZ::IsEnabled() and TIL_FEATURE_XYZ_ENABLED (preprocessor) -->

View File

@@ -74,7 +74,7 @@ Should not affect security.
### Reliability
Aside from additional parsing required for the settings file (which inherently offers more locations for parsing to fail), we need to be careful about badly formed/non-existent feature tags or axes specified in the user-defined dictionaries. We must make sure to ignore such declarations (perhaps alongside emitting a warning to the user) and only apply those that are correctly formed and exist.
Aside from additional parsing required for the settings file (which inherently offers more locations for parsing to fail), we need to be careful about badly formed/nonexistent feature tags or axes specified in the user-defined dictionaries. We must make sure to ignore such declarations (perhaps alongside emitting a warning to the user) and only apply those that are correctly formed and exist.
### Compatibility

View File

@@ -138,7 +138,7 @@ The delegation repeats the same dance as above as well:
The terminal will be its own complete presentation and input solution on top of a ConPTY connection, separating the concerns between API servicing and the user experience.
Today the Terminal knows how to start and then launches a ConPTY under it. The Terminal will need to be updated to accept a pre-existing ConPTY connection on launch (or when the multi-process model arrives, as an inbound connection), and connect that to a new tab/pane instead of using the `winconpty.lib` libraries to make its own.
Today the Terminal knows how to start and then launches a ConPTY under it. The Terminal will need to be updated to accept a preexisting ConPTY connection on launch (or when the multi-process model arrives, as an inbound connection), and connect that to a new tab/pane instead of using the `winconpty.lib` libraries to make its own.
For now, I'm considering only the fresh-start scenario.
- The Terminal will have to detect the inbound connection through ~~its argument parsing (or through~~ a new entrypoint in the COM alternative ~~)~~ and store the PTY in/out/signal handles for that connection in the startup arguments information

View File

@@ -0,0 +1,281 @@
---
author: Carlos Zamora @carlos-zamora
created on: 2019-08-30
last updated: 2022-07-06
issue id: 715
---
# Keyboard Selection
## Abstract
This spec describes a new set of key bindings that allows the user to create and update a selection without the use of a mouse or stylus.
## Inspiration
ConHost allows the user to modify a selection using the keyboard. Holding `Shift` allows the user to move the second selection endpoint in accordance with the arrow keys. The selection endpoint updates by one cell per key event, allowing the user to refine the selected region.
### Creating a selection
Mark Mode is a ConHost feature that allows the user to create a selection using only the keyboard. In CMD, pressing <kbd>ctrl+m</kbd> enters mark mode. The current cursor position becomes a selection endpoint. The user can use the arrow keys to move that endpoint. While the user then holds <kbd>shift</kbd>, the selection endpoint ('start') is anchored to it's current position, and the arrow keys move the other selection endpoint ('end').
Additionally, pressing <kbd>shift+arrow</kbd> also initiates a selection, but it anchors the first selection endpoint to the cursor position.
Other terminal emulators have different approaches to this feature. iTerm2, for example, has Copy Mode (documentation [linked here](https://iterm2.com/documentation-copymode.html)). Here, <kbd>cmd+shift+c</kbd> makes the current cursor position become a selection endpoint. The arrow keys can be used to move that endpoint. However, unlike Mark Mode, a key binding <kbd>c+space</kbd> is used to change the start/stop selecting. The first time it's pressed, the 'start' endpoint is anchored. The second time it's pressed, the 'end' endpoint is set. After this, you can still move a cursor, but the selection persists until a new selection is created (either by pressing the key binding again, or using the mouse).
Though tmux is not a terminal emulator, it does also have Copy Mode that behaves fairly similarly to that of iTerm2's.
## Solution Design
The fundamental solution design for keyboard selection is that the responsibilities between the Terminal Control and Terminal Core must be very distinct. The Terminal Control is responsible for handling user interaction and directing the Terminal Core to update the selection. The Terminal Core will need to update the selection according to the direction of the Terminal Control. Terminal Core maintains the state of the selection.
Relatively recently, TerminalControl was split into `TerminalControl`, `ControlInteractivity`, and `ControlCore`. Changes made to `ControlInteractivity`, `ControlCore`, and below propagate functionality to all consumers, meaning that the WPF terminal would benefit from these changes with no additional work required.
### Fundamental Terminal Control Changes
`ControlCore::TrySendKeyEvent()` is responsible for handling the key events after key bindings are dealt with in `TermControl`. At the time of writing this spec, there are 2 cases handled in this order:
- Clear the selection (except in a few key scenarios)
- Send Key Event
The first branch will be updated to _modify_ the selection instead of usually _clearing_ it. This will happen by converting the key event into parameters to forward to `TerminalCore`, which then updates the selection appropriately.
#### Abandoned Idea: Make keyboard selection a collection of standard keybindings
One idea is to introduce an `updateSelection` action that conditionally works if a selection is active (similar to the `copy` action). For these key bindings, if there is no selection, the key events are forwarded to the application.
Thanks to Keybinding Args, there would only be 1 new command:
| Action | Keybinding Args | Description |
|--|--|--|
| `updateSelection` | | If a selection exists, moves the last selection endpoint. |
| | `Enum direction { up, down, left, right }` | The direction the selection will be moved in. |
| | `Enum mode { char, word, view, buffer }` | The context for which to move the selection endpoint to. (defaults to `char`) |
By default, the following keybindings will be set:
```JS
// Character Selection
{ "command": {"action": "updateSelection", "direction": "left", "mode": "char" }, "keys": "shift+left" },
{ "command": {"action": "updateSelection", "direction": "right", "mode": "char" }, "keys": "shift+right" },
{ "command": {"action": "updateSelection", "direction": "up", "mode": "char" }, "keys": "shift+up" },
{ "command": {"action": "updateSelection", "direction": "down", "mode": "char" }, "keys": "shift+down" },
// Word Selection
{ "command": {"action": "updateSelection", "direction": "left", "mode": "word" }, "keys": "ctrl+shift+left" },
{ "command": {"action": "updateSelection", "direction": "right", "mode": "word" }, "keys": "ctrl+shift+right" },
// Viewport Selection
{ "command": {"action": "updateSelection", "direction": "left", "mode": "view" }, "keys": "shift+home" },
{ "command": {"action": "updateSelection", "direction": "right", "mode": "view" }, "keys": "shift+end" },
{ "command": {"action": "updateSelection", "direction": "up", "mode": "view" }, "keys": "shift+pgup" },
{ "command": {"action": "updateSelection", "direction": "down", "mode": "view" }, "keys": "shift+pgdn" },
// Buffer Corner Selection
{ "command": {"action": "updateSelection", "direction": "up", "mode": "buffer" }, "keys": "ctrl+shift+home" },
{ "command": {"action": "updateSelection", "direction": "down", "mode": "buffer" }, "keys": "ctrl+shift+end" },
```
These are in accordance with ConHost's keyboard selection model.
This idea was abandoned due to several reasons:
1. Keyboard selection should be a standard way to interact with a terminal across all consumers (i.e. WPF control, etc.)
2. There isn't really another set of key bindings that makes sense for this. We already hardcoded <kbd>ESC</kbd> as a way to clear the selection. This is just an extension of that.
3. Adding 12 conditionally effective key bindings takes the spot of 12 potential non-conditional key bindings. It would be nice if a different key binding could be set when the selection is not active, but that makes the settings design much more complicated.
4. 12 new items in the command palette is also pretty excessive.
5. If proven wrong when this is in WT Preview, we can revisit this and make them customizable then. It's better to add the ability to customize it later than take it away.
#### Abandoned Idea: Make keyboard selection a simulation of mouse selection
It may seem that some effort can be saved by making the keyboard selection act as a simulation of mouse selection. There is a union of mouse and keyboard activity that can be represented in a single set of selection motion interfaces that are commanded by the TermControl's Mouse/Keyboard handler and adapted into appropriate motions in the Terminal Core.
However, the mouse handler operates by translating a pixel coordinate on the screen to a text buffer coordinate. This would have to be rewritten and the approach was deemed unworthy.
### Fundamental Terminal Core Changes
The Terminal Core will need to expose a `UpdateSelection()` function that is called by the keybinding handler. The following parameters will need to be passed in:
- `enum SelectionDirection`: the direction that the selection endpoint will attempt to move to. Possible values include `Up`, `Down`, `Left`, and `Right`.
- `enum SelectionExpansion`: the selection expansion mode that the selection endpoint will adhere to. Possible values include `Char`, `Word`, `View`, `Buffer`.
#### Moving by Cell
For `SelectionExpansion = Char`, the selection endpoint will be updated according to the buffer's output pattern. For **horizontal movements**, the selection endpoint will attempt to move left or right. If a viewport boundary is hit, the endpoint will wrap appropriately (i.e.: hitting the left boundary moves it to the last cell of the line above it).
For **vertical movements**, the selection endpoint will attempt to move up or down. If a **viewport boundary** is hit and there is a scroll buffer, the endpoint will move and scroll accordingly by a line.
If a **buffer boundary** is hit, the endpoint will not move. In this case, however, the event will still be considered handled.
**NOTE**: An important thing to handle properly in all cases is wide glyphs. The user should not be allowed to select a portion of a wide glyph; it should be all or none of it. When calling `_ExpandWideGlyphSelection` functions, the result must be saved to the endpoint.
#### Moving by Word
For `SelectionExpansion = Word`, the selection endpoint will also be updated according to the buffer's output pattern, as above. However, the selection will be updated in accordance with "chunk selection" (performing a double-click and dragging the mouse to expand the selection). For **horizontal movements**, the selection endpoint will be updated according to the `_ExpandDoubleClickSelection` functions. The result must be saved to the endpoint. As before, if a boundary is hit, the endpoint will wrap appropriately. See [Future Considerations](#FutureConsiderations) for how this will interact with line wrapping.
For **vertical movements**, the movement is a little more complicated than before. The selection will still respond to buffer and viewport boundaries as before. If the user is trying to move up, the selection endpoint will attempt to move up by one line, then selection will be expanded leftwards. Alternatively, if the user is trying to move down, the selection endpoint will attempt to move down by one line, then the selection will be expanded rightwards.
#### Moving by Viewport
For `SelectionExpansion = View`, the selection endpoint will be updated according to the viewport's height. Horizontal movements will be updated according to the viewport's width, thus resulting in the endpoint being moved to the left/right boundary of the viewport.
#### Moving by Buffer
For `SelectionExpansion = Buffer`, the selection endpoint will be moved to the beginning or end of all the text within the buffer. If moving up or left, set the position to 0,0 (the origin of the buffer). If moving down or right, set the position to the last character in the buffer.
**NOTE**: In all cases, horizontal movements attempting to move past the left/right viewport boundaries result in a wrap. Vertical movements attempting to move past the top/bottom viewport boundaries will scroll such that the selection is at the edge of the screen. Vertical movements attempting to move past the top/bottom buffer boundaries will be clamped to be within buffer boundaries.
**NOTE**: If `copyOnSelect` is enabled, we need to make sure we **DO NOT** update the clipboard on every change in selection. The user must explicitly choose to copy the selected text from the buffer.
### Mark Mode
Mark Mode is a mode where the user can create and modify a selection using only the keyboard.
When no selection is present, the user may use the `markMode` action to enter mark mode. Upon doing so, a selection will be created at the current cursor position.
When in mark mode, the user may...
- press <kbd>ESC</kbd> to clear the selection and exit mark mode
- invoke the `markMode` action to exit mark mode
- invoke the `copy` action (this includes right-clicking the terminal) to copy the selected text, clear the selection, and exit mark mode
- move the cursor in the following ways:
- arrow keys --> move by character
- ctrl + left/right --> move by word
- ctrl + home/end --> move to the beginning/end of the buffer
- home/end --> move to the beginning/end of the line respectively
- pgup/pgdn --> move up/down by viewport respectively
- expand the selection in the following ways:
- shift + arrow keys --> move the "end" endpoint by character
- ctrl + shift + left/right --> move the "end" endpoint by word
- ctrl + shift + home/end --> move the "end" endpoint to the beginning/end of the buffer
- shift + home/end --> move the "end" endpoint to the beginning/end of the line respectively
- shift + pgup/pgdn --> move the "end" endpoint up/down by viewport respectively
As with mouse selections, keybindings are still respected and pressing a key that is not bound to a keybinding (or mentioned above) will clear the selection and exit mark mode.
#### Corner cases
- In mark mode, if a selection was created via the keyboard, moving the cursor moves at the "end" endpoint. This is consistent with conhost.
- If a user creates a selection using the mouse, then enters mark mode, mark mode inherits the existing selection as if it was made using the keyboard.
- If `copyOnSelect` is enabled, the selection is copied when the selection operation is "complete". Thus, the selection is copied when the `copy` keybinding is used or the selection is copied using the mouse.
- If `copyOnSelect` is enabled, `ESC` is interpreted as "cancelling" the selection, so nothing is copied. Keys that generate input are also interpreted as "cancelling" the selection. Only the `copy` keybinding or copying using the mouse is considered "completing" the selection operation, and copying the content to the clipboard.
**NOTE** - Related to #3884:
If the user has chosen to have selections persist after a copy operation, the selection created by Copy Mode is treated no differently than one created with the mouse. The selection will persist after a copy operation. However, if the user exits Copy Mode in any of the other situations, the selection is cleared.
#### Block Selection
A user can normally create a block selection by holding <kbd>alt</kbd> then creating a selection.
If the user is in Mark Mode, and desires to make a block selection, they can use the `toggleBlockSelection()` action. `toggleBlockSelection()` takes an existing selection, and transforms it into a block selection (or vice-versa).
All selections created in Mark Mode will have block selection disabled by default.
#### Rendering during Copy Mode
Since we are just moving the selection endpoints, rendering the selection rects should operate normally. We need to ensure that we still scroll when we move a selection point past the top/bottom of the viewport.
In ConHost, output would be paused when a selection was present. Windows Terminal does not pause the output when a selection is present, however, it does not scroll to the new output.
#### Interaction with Mouse Selection
If a selection exists, the user is basically already in Copy Mode. The user should be modifying the "end" endpoint of the selection when using the `updateSelection()` bindings. The existing selection should not be cleared (contrary to prior behavior). However, the half-y-beam will not be drawn. Once the user presses the `copyMode` or `moveSelectionPoint` keybinding, the half-y-beam is drawn on the targeted endpoint (which will then be "start").
During Copy Mode, if the user attempts to create a selection using the mouse, any existing selections are cleared and the mouse creates a selection normally. However, contrary to prior behavior, the user will still be in Copy Mode. The target endpoint being modified in Copy Mode, however, will be the "end" endpoint of the selection, instead of the cursor (as explained earlier in the flowchart).
#### Abandoned Idea: Copy Mode
Copy Mode is a more complex version of Mark Mode that is intended to provide a built-in way to switch the active selection endpoint. This idea was abandoned because we would then run into a user education issue. Rather than reinventing the wheel, selection should feel natural like that of a text editor, and any diversion from that model should be introduced separately (i.e. keybindings). Doing so ensures that users can "hit the ground running" when trying to make a selection, but won't be hindered by new functionality that is available.
Copy Mode is a mode where the user can create and modify a selection using only the keyboard. The following flowchart covers how the new `copymode()` action works:
![Copy Mode Flowchart][images/CopyModeFlowchart.png]
**NOTE**: `copyMode()` refers to the action, whereas `updateSelection()` refers to the underlying function that is being called in the code.
If a selection is not active, a "start" and "end" selection point is created at the cursor position. `updateSelection()` calls then move "start" and "end" together as one position.
Invoking `copyMode()` again, will then anchor "start" (meaning that it will be kept in place). Subsequent `updateSelection()` calls move the "end" selection point.
Invoking `copyMode()` essentially cycles between which selection point is targeted.
## UI/UX Design
### Key Bindings
| Action | Keybinding Args | Description |
|--|--|--|
| `selectAll` | none | Select the entire text buffer. |
| `markMode` | none | Toggle mark mode. If no selection exists, create a selection at the cursor position. Otherwise, use the existing selection as one in mark mode. |
| `toggleBlockSelection` | none | Transform the existing selection between a block selection and a line selection. |
| `switchSelectionEndpoint` | none | If a selection is present, switch which selection endpoint is targeted when in mark mode or another keyboard selection mode (i.e. modified a mouse selection using the keyboard). |
By default, the following key binding will be set:
```JS
{ "command": "selectAll", "keys": "ctrl+shift+a" },
// Copy Mode
{ "command": "copyMode", "keys": "ctrl+shift+m" },
{ "command": "toggleBlockSelection" },
{ "command": "switchSelectionEndpoint" },
```
### Selection Markers
A y-beam will be used to identify which selection endpoint is currently being moved when in mark mode. The y-beam will match the cursor color and the font size so that it essentially fills a cell in the buffer.
When we're moving the cursor (this happens when mark mode is entered from no existing selection), a full y-beam will be displayed at the cursor position.
![Y-Beam Example](./images/Y-Beam.png)
When <kbd>shift</kbd> is held, we're expanding the selection. In this case, the y-beam will be split, and the relevant half will be rendered on the active endpoint functioning as a selection marker.
![Separated Y-Beam Example](./images/Half-Y-Beam.png)
If the selection is up against the end (or beginning) of the line, the selection marker can't be rendered normally because there is no space to render it off the side of the terminal. Instead, the selection marker will be horizontally flipped. Alternatively, it can be rendered on the next available cell (i.e. end of line translates to the beginning of the next line), but that would cause issues when the selection is positioned at the beginning or end of the buffer, thus the idea was abandoned.
If the active endpoint crosses the inactive endpoint, the selection marker will be flipped. In a sense, the flag will always point away from the selection.
The y-beam doesn't make as much sense for block selections, so instead an L-shaped marker will be placed hugging the corner of the active selection endpoint.
**NOTE:** Both half y-beams could have been presented as shown in the image below. This idea was omitted because then there is no indication for which half y-beam is currently focused.
![Both Separated Y-Beams Example](./images/Split-Y-Beam.png)
### Miscellaneous
When mark mode is enabled, the cursor will stop blinking.
## Capabilities
### Accessibility
Using the keyboard is generally a more accessible experience than using the mouse. Being able to modify a selection by using the keyboard is a good first step towards making selecting text more accessible.
We will be expected to send "selection changed" events via UIA every time the cursor moves or selection updates (both are considered the same event).
### Security
N/A
### Reliability
With regards to the Terminal Core, the newly introduced code should rely on already existing and tested code. Thus no crash-related bugs are expected.
With regards to Terminal Control and the settings model, crash-related bugs are not expected. However, ensuring that the selection is updated and cleared in general use-case scenarios must be ensured.
### Compatibility
N/A
### Performance, Power, and Efficiency
N/A
## Potential Issues
### Grapheme Clusters
When grapheme cluster support is inevitably added to the Text Buffer, moving by "cell" is expected to move by "character" or "cluster". This is similar to how wide glyphs are handled today. Either all of it is selected, or none of it.
### Circling the buffer
As usual, if the buffer is circling, the selection should be updated to follow the content (and "scroll up" appropriately).
In the event that one endpoint "scrolls" off the buffer, we must clamp "start" to the buffer origin. Conversely, in the event that both endpoints "scroll" off the buffer, the selection must be considered cleared.
## Future considerations
### Word Selection Wrap
At the time of writing this spec, expanding or moving by word is interrupted by the beginning or end of the line, regardless of the wrap flag being set. In the future, selection and the accessibility models will respect the wrap flag on the text buffer.
## Resources
- https://blogs.windows.com/windowsdeveloper/2014/10/07/console-improvements-in-the-windows-10-technical-preview/

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

View File

@@ -659,7 +659,7 @@ loading until that generator is complete.
However, if the user disables that generator entirely, we'll never display that
profile to the user, even if they've done that setup before.
So the trade-off with this design is that non-existent dynamic profiles will
So the trade-off with this design is that nonexistent dynamic profiles will
never roam to machines where they don't exist and aren't valid, but the
generators _must_ be enabled to use the dynamic profiles.

View File

@@ -204,7 +204,7 @@ We need a way to determine where an action came from to minimize how many action
- Construct the `Command` (basically the `Command::LayerJson` we have today)
- Add it to the `ActionMap`
- this should update the internal state of `ActionMap` appropriately
- if the newly added key chord conflicts with a pre-existing one,
- if the newly added key chord conflicts with a preexisting one,
redirect `_KeyMap` to the newly added `Command` instead,
and update the conflicting one.
2. Load settings.json

View File

@@ -1,171 +0,0 @@
---
author: Carlos Zamora @carlos-zamora
created on: 2019-08-30
last updated: 2021-09-17
issue id: 715
---
# Keyboard Selection
## Abstract
This spec describes a new set of non-configurable keybindings that allows the user to update a selection without the use of a mouse or stylus.
## Inspiration
ConHost allows the user to modify a selection using the keyboard. Holding `Shift` allows the user to move the second selection endpoint in accordance with the arrow keys. The selection endpoint updates by one cell per key event, allowing the user to refine the selected region.
Mark mode allows the user to create a selection using only the keyboard, then edit it as mentioned above.
## Solution Design
The fundamental solution design for keyboard selection is that the responsibilities between the Terminal Control and Terminal Core must be very distinct. The Terminal Control is responsible for handling user interaction and directing the Terminal Core to update the selection. The Terminal Core will need to update the selection according to the preferences of the Terminal Control.
Relatively recently, TerminalControl was split into `TerminalControl`, `ControlInteractivity`, and `ControlCore`. Changes made to `ControlInteractivity`, `ControlCore`, and below propagate functionality to all consumers, meaning that the WPF terminal would benefit from these changes with no additional work required.
### Fundamental Terminal Control Changes
`ControlCore::TrySendKeyEvent()` is responsible for handling the key events after key bindings are dealt with in `TermControl`. At the time of writing this spec, there are 2 cases handled in this order:
- Clear the selection (except in a few key scenarios)
- Send Key Event
The first branch will be updated to _modify_ the selection instead of usually _clearing_ it. This will happen by converting the key event into parameters to forward to `TerminalCore`, which then updates the selection appropriately.
#### Idea: Make keyboard selection a collection of standard keybindings
One idea is to introduce an `updateSelection` action that conditionally works if a selection is active (similar to the `copy` action). For these key bindings, if there is no selection, the key events are forwarded to the application.
Thanks to Keybinding Args, there would only be 1 new command:
| Action | Keybinding Args | Description |
|--|--|--|
| `updateSelection` | | If a selection exists, moves the last selection endpoint. |
| | `Enum direction { up, down, left, right }` | The direction the selection will be moved in. |
| | `Enum mode { char, word, view, buffer }` | The context for which to move the selection endpoint to. (defaults to `char`) |
By default, the following keybindings will be set:
```JS
// Character Selection
{ "command": {"action": "updateSelection", "direction": "left", "mode": "char" }, "keys": "shift+left" },
{ "command": {"action": "updateSelection", "direction": "right", "mode": "char" }, "keys": "shift+right" },
{ "command": {"action": "updateSelection", "direction": "up", "mode": "char" }, "keys": "shift+up" },
{ "command": {"action": "updateSelection", "direction": "down", "mode": "char" }, "keys": "shift+down" },
// Word Selection
{ "command": {"action": "updateSelection", "direction": "left", "mode": "word" }, "keys": "ctrl+shift+left" },
{ "command": {"action": "updateSelection", "direction": "right", "mode": "word" }, "keys": "ctrl+shift+right" },
// Viewport Selection
{ "command": {"action": "updateSelection", "direction": "left", "mode": "view" }, "keys": "shift+home" },
{ "command": {"action": "updateSelection", "direction": "right", "mode": "view" }, "keys": "shift+end" },
{ "command": {"action": "updateSelection", "direction": "up", "mode": "view" }, "keys": "shift+pgup" },
{ "command": {"action": "updateSelection", "direction": "down", "mode": "view" }, "keys": "shift+pgdn" },
// Buffer Corner Selection
{ "command": {"action": "updateSelection", "direction": "up", "mode": "buffer" }, "keys": "ctrl+shift+home" },
{ "command": {"action": "updateSelection", "direction": "down", "mode": "buffer" }, "keys": "ctrl+shift+end" },
```
These are in accordance with ConHost's keyboard selection model.
This idea was abandoned due to several reasons:
1. Keyboard selection should be a standard way to interact with a terminal across all consumers (i.e. WPF control, etc.)
2. There isn't really another set of key bindings that makes sense for this. We already hardcoded <kbd>ESC</kbd> as a way to clear the selection. This is just an extension of that.
3. Adding 12 conditionally effective key bindings takes the spot of 12 potential non-conditional key bindings. It would be nice if a different key binding could be set when the selection is not active, but that makes the settings design much more complicated.
4. 12 new items in the command palette is also pretty excessive.
5. If proven wrong when this is in WT Preview, we can revisit this and make them customizable then. It's better to add the ability to customize it later than take it away.
#### Idea: Make keyboard selection a simulation of mouse selection
It may seem that some effort can be saved by making the keyboard selection act as a simulation of mouse selection. There is a union of mouse and keyboard activity that can be represented in a single set of selection motion interfaces that are commanded by the TermControl's Mouse/Keyboard handler and adapted into appropriate motions in the Terminal Core.
However, the mouse handler operates by translating a pixel coordinate on the screen to a text buffer coordinate. This would have to be rewritten and the approach was deemed unworthy.
### Fundamental Terminal Core Changes
The Terminal Core will need to expose a `UpdateSelection()` function that is called by the keybinding handler. The following parameters will need to be passed in:
- `enum SelectionDirection`: the direction that the selection endpoint will attempt to move to. Possible values include `Up`, `Down`, `Left`, and `Right`.
- `enum SelectionExpansion`: the selection expansion mode that the selection endpoint will adhere to. Possible values include `Char`, `Word`, `View`, `Buffer`.
#### Moving by Cell
For `SelectionExpansion = Char`, the selection endpoint will be updated according to the buffer's output pattern. For **horizontal movements**, the selection endpoint will attempt to move left or right. If a viewport boundary is hit, the endpoint will wrap appropriately (i.e.: hitting the left boundary moves it to the last cell of the line above it).
For **vertical movements**, the selection endpoint will attempt to move up or down. If a **viewport boundary** is hit and there is a scroll buffer, the endpoint will move and scroll accordingly by a line.
If a **buffer boundary** is hit, the endpoint will not move. In this case, however, the event will still be considered handled.
**NOTE**: An important thing to handle properly in all cases is wide glyphs. The user should not be allowed to select a portion of a wide glyph; it should be all or none of it. When calling `_ExpandWideGlyphSelection` functions, the result must be saved to the endpoint.
#### Moving by Word
For `SelectionExpansion = Word`, the selection endpoint will also be updated according to the buffer's output pattern, as above. However, the selection will be updated in accordance with "chunk selection" (performing a double-click and dragging the mouse to expand the selection). For **horizontal movements**, the selection endpoint will be updated according to the `_ExpandDoubleClickSelection` functions. The result must be saved to the endpoint. As before, if a boundary is hit, the endpoint will wrap appropriately. See [Future Considerations](#FutureConsiderations) for how this will interact with line wrapping.
For **vertical movements**, the movement is a little more complicated than before. The selection will still respond to buffer and viewport boundaries as before. If the user is trying to move up, the selection endpoint will attempt to move up by one line, then selection will be expanded leftwards. Alternatively, if the user is trying to move down, the selection endpoint will attempt to move down by one line, then the selection will be expanded rightwards.
#### Moving by Viewport
For `SelectionExpansion = View`, the selection endpoint will be updated according to the viewport's height. Horizontal movements will be updated according to the viewport's width, thus resulting in the endpoint being moved to the left/right boundary of the viewport.
#### Moving by Buffer
For `SelectionExpansion = Buffer`, the selection endpoint will be moved to the beginning or end of all the text within the buffer. If moving up or left, set the position to 0,0 (the origin of the buffer). If moving down or right, set the position to the last character in the buffer.
**NOTE**: In all cases, horizontal movements attempting to move past the left/right viewport boundaries result in a wrap. Vertical movements attempting to move past the top/bottom viewport boundaries will scroll such that the selection is at the edge of the screen. Vertical movements attempting to move past the top/bottom buffer boundaries will be clamped to be within buffer boundaries.
Every combination of the `SelectionDirection` and `SelectionExpansion` will map to a keybinding. These pairings are shown below in the UI/UX Design --> Keybindings section.
**NOTE**: If `copyOnSelect` is enabled, we need to make sure we **DO NOT** update the clipboard on every change in selection. The user must explicitly choose to copy the selected text from the buffer.
## UI/UX Design
### Key Bindings
There will only be 1 new command that needs to be added:
| Action | Keybinding Args | Description |
|--|--|--|
| `selectAll` | | Select the entire text buffer.
By default, the following key binding will be set:
```JS
{ "command": "selectAll", "keys": "ctrl+shift+a" },
```
## Capabilities
### Accessibility
Using the keyboard is generally a more accessible experience than using the mouse. Being able to modify a selection by using the keyboard is a good first step towards making selecting text more accessible.
### Security
N/A
### Reliability
With regards to the Terminal Core, the newly introduced code should rely on already existing and tested code. Thus no crash-related bugs are expected.
With regards to Terminal Control and the settings model, crash-related bugs are not expected. However, ensuring that the selection is updated and cleared in general use-case scenarios must be ensured.
### Compatibility
N/A
### Performance, Power, and Efficiency
## Potential Issues
### Grapheme Clusters
When grapheme cluster support is inevitably added to the Text Buffer, moving by "cell" is expected to move by "character" or "cluster". This is similar to how wide glyphs are handled today. Either all of it is selected, or none of it.
## Future considerations
### Word Selection Wrap
At the time of writing this spec, expanding or moving by word is interrupted by the beginning or end of the line, regardless of the wrap flag being set. In the future, selection and the accessibility models will respect the wrap flag on the text buffer.
## Mark Mode
This functionality will be expanded to create a feature similar to Mark Mode. This will allow a user to create a selection using only the keyboard.
## Resources
- https://blogs.windows.com/windowsdeveloper/2014/10/07/console-improvements-in-the-windows-10-technical-preview/

View File

@@ -17,7 +17,7 @@ This spec will outline how various terminal frontends will be able to interact w
Terminal component.
* **Terminal Layer**: This is the shared core implementation of the terminal.
This is the Terminal Connection, Parser/Adapter, Buffer, and Renderer (but not
the UX-dependant RenderEngine).
the UX-dependent RenderEngine).
## User Stories
1. "Project Cascadia" should be able to have both global settings (such as

View File

@@ -0,0 +1,243 @@
---
author: Mike Griese @zadjii-msft
created on: 2022-02-15
last updated: 2022-04-25
issue id: #10509
---
# Mica in the Terminal
## Abstract
This document serves as a companion doc to the [Theming Spec], rather than a
spec on it's own. The context of broader application-level theming support is
necessary to understand the big picture of the designs in this discussion.
This spec is intended to help understand the problem space of adding [Mica] to
the Windows Terminal. Introduced in Windows 11, Mica is a new type of material
that incorporates theme and desktop wallpaper to paint the background of
windows. The effect results in a blurred, transparency-like effect, quite
similar to [Acrylic]. However, the technical limitations of Mica make it more
complicated to integrate seamlessly with the Terminal experience.
## Background
Mica is a material that can only be applied to the root of the UI tree, and
applies to the entire background surface. It's recommended to be used at the
`Page` level, in place of a solid brush like
`ApplicationPageBackgroundThemeBrush`. If the developer wants a surface within
the page to have a Mica background, they need to make sure to have that element
(and all elements behind it up until the `Page`) have a `Transparent`
background, so that Mica will be visible through the elements.
This is contrasted with something like Acrylic, where the acrylic effect is
specified at the Element layer itself. An element can request having a
`HostBackdrop` brush for its background, and the element will have the Acrylic
effect regardless of the structure of the rest of the elements in the UI tree.
Another important use case here is "Vintage Transparency" (or "unblurred
transparency"), which is an unblurred transparency effect for the Terminal
window. This is achieved with the `TransparentBackground` API, which enables the
Terminal to disable the emergency backstop of the XAML Island. When that's
enabled, controls that are transparent will be blended, unblurred, with whatever
is visible behind the window. This works because the entire tree of the Terminal
window underneath the `TermControl`s are `Transparent`, all the way up to the
window itself.
Right now, the Terminal exposes three settings<sup>[[1]](#footnote-1)</sup>:
* Background color
* Background Opacity
* Whether the user would like to enable acrylic or not
These settings are exposed at the "Profile"<sup>[[2]](#footnote-2)</sup> level.
Properties on a profile are roughly considered to be "what the terminal control
will look like when I run this settings profile". Users can have one profile
with acrylic, one without, and open [Panes] with these profiles side-by-side in
the Terminal. It's entirely possible that a user would have both a pane with and
acrylic background, and one with an unblurred background in the same window.
### User Stories
* The Terminal should be able to have Mica in the title bar, behind the tabs.
* Users will want Mica in the control area, as well as in the titlebar
* Users may want Mica in the control, but with a solid titlebar, or an accent
colored title bar, or an acrylic one...
* Users will want mica in the titlebar with other effects (acrylic, vintage
transparency) in the control area
This is where things get complicated. Given that a control can choose what type
of material it has now, users would likely expect to be able to choose between
acrylic, unblurred transparency, or Mica. However, Mica can only be applied at
the root of the window. It's applied behind everything else in the window. From
an implementation standpoint, Mica is a window-level property, not a control
level one. If we want to have Mica under one control, we need to enable it for
the _whole window_. If we enable Mica for the whole window, that would
simultaneously prevent Vintage Transparency from working as expected. This is
because the semi-transparent controls would no longer have a fully transparent
window background to sit on top of - they'd be blended instead with the Mica
background behind the window.
## Solution design
### Mica for `TermControl`s
If we make enabling Mica for the control a per-profile setting, I believe that
will lead to greater user confusion. It would result in "spooky action at a
distance", where creating any pane with Mica would force the entire window to
have a Mica background. This would change the appearance of any other unblurred
transparent panes in the window, causing them to also be subjected to the Mica
treatment as well.
**Proposal**: create a window-level theme property `window.background.useMica`
(or similar), which will enable Mica for the entire window. When enabled, users
can use a fully transparent, unblurred background for their profile to achieve
the Mica effect within the control. When enabled, users **won't** be able to see
through to the desktop with any vintage opacity settings.
By nesting Mica usage under `"window.background"`, it will be clearer that it's
something that applies to the whole window, as the background for everything.
I believe this is the most acceptable way to expose Mica to our users without
"spooky action at a distance".
An example of what mica in the control area might look like:
![Mica in the TermControl](./mica-in-control-000.png)
### Mica in the titlebar
To achieve Mica in the titlebar, we'll similarly need to allow users to set the
titlebar area to totally transparent, to allow the mica behind the window to be
visible. A simple theme to achieve that might look like:
```jsonc
{
"theme": "My Mica Titlebar Theme",
"themes": [
{
"name": "My Mica Titlebar Theme",
"window":{
"background.useMica": true, // Use mica behind the window
},
"tabRow":{
"background": "#00000000", // Make the TabView Transparent
}
}
]
}
```
As noted before, due to the intentional limitations of the Mica material, if the
user wants Mica in the tab row, they won't be able to use vintage opacity in any
controls. The vintage opacity of the controls will show through to the Mica
layer, instead of transparent through the whole window.
## Considered implementations
* We experimented with a new DWM API in SV2 which should enable us to set the
background of our window to Mica. This did seem to work for the root window.
It however, did not seem to work for the "drag window", the child HWND which
we use to intercept nonclient messages in our titlebar area. Apparently, that
API does not work at all for `WS_CHILD` windows, by design. This unfortunately
prevents us from allowing Mica only in the titlebar area, without also
applying it to the rest of the main window.
* We considered rolling our own Mica brush to allow us to style individual
elements. This didn't seem terribly hard at face value, considering [the Mica
recipe] is basically open-source. However, it seems to rely on some
closed-source `IGraphicsEffect`s from the `Composition.Effects` namespace.
Apparently, those effects are only [implemented in Win2D]. It's unclear at
this time if the Terminal would be capable of ingesting Win2D now or in the
future. It does seem as though [Win2D is available via cppwinrt], so that's of
some solace.
**However**, that does leave us in the world where we're rolling our own
custom Mica brush, and would need to keep it up to date with the OS
implementation. We'd be firmly off the rails of the recommended Mica usage,
and our support would be likely very minimal. This is reason alone to
avoid this path, and instead push for a platform-supported solution.
**TODO!**: We should make sure to have a Future Considerations section on how
we'd implement per-element Mica, should that option be available to us in the
future.
## Potential Issues
This is not a particularly ergonomic design. From a UX perspective, the user
needs to enable one setting in the UI to enable Mica, and then go to profile
settings to set the profile to _transparent_ for each of the profiles they want
with Mica. That's not very intuitive by any means.
Mica would also impact our ability to enable the "acrylic on an unfocused
window" functionality, requested in [#7158]. To support that feature, we need to
have a transparent window backdrop, so that the in-app acrylic will magically
use the desktop background. With Mica and this setting enabled, the acrylic
would apply on top of the Mica layer. Either warnings would need to be
displayed, or one setting would have to disable the other. At the very least,
the documentation needs to be very clear about this.
In [this comment], the poster shows a pretty cool mockup of what a background
image for the _window_ might look like. This kinda fills a similar problem space
as Mica. If there were a background image for the whole Terminal window, then
in-app acrylic would apply on top of the image. Vintage transparency wouldn't
work through the image, it would apply on _top_ of the image. Perhaps, because
of these related concerns, there should be a singular `window.background`
property, that contains an object of settings. Or, to follow the solely dot
notation from before
```jsonc
{
"theme": "My Background Theme",
"themes": [
{
"name": "My Background Theme",
"window":{
"background.useMica": true, // Use mica behind the window
"background.image": "some/path/to/image", // Use a BG image
"background.imageOpacity": 25, // Image is mostly transparent
},
"tabRow":{
"background": "#00000000", // Make the TabView Transparent
}
}
],
"profiles": {
"defaults": {
"opacity": 0 // Panes are all totally transparent
}
}
}
```
## Future considerations
* I believe Insiders builds have support for two different variants of Mica -
standard Mica, and "Thin" Mica. We may need to support a future enum value
here, with values `"none", "original", "thin"`. For compatibility with the
boolean values, `true=="original"`, `false=="none"`.
## Resources
### Footnotes
<a name="footnote-1"><a>[1]: For simplicity of the spec, I'm ignoring the
background image settings. I'm also ignoring the small quirk where (at the time
of writing), vintage opacity doesn't work on Windows 10. That creates some weird
quirks where acrylic is always enabled if the user wants transparency on Windows
10. A full discussion of this would only serve to complicate what is
fundamentally a Windows 11-centric discussion.
<a name="footnote-2"><a>[2]: We're also gonna leave out a discussion of focused
& unfocused "appearance" setting objects, again for brevity.
[Theming Spec]: ./%233327%20-%20Application%20Theming.md
[Mica]: https://docs.microsoft.com/en-us/windows/apps/design/style/mica
[Acrylic]: https://docs.microsoft.com/en-us/windows/apps/design/style/acrylic
[Panes]: https://docs.microsoft.com/en-us/windows/terminal/panes
[#3327]: https://github.com/microsoft/terminal/issues/3327
[#10509]: https://github.com/microsoft/terminal/issues/10509
[#7158]: https://github.com/microsoft/terminal/issues/7158
[this comment]: https://github.com/microsoft/terminal/issues/3327#issuecomment-765493313
[the Mica recipe]: https://github.com/microsoft/microsoft-ui-xaml/blob/0db5d0398cb38d69b06e26ef734cbbdebdebe774/dev/Materials/Backdrop/SystemBackdropBrushFactory.cpp#L8-L54
[implemented in Win2D]: https://docs.microsoft.com/en-us/uwp/api/windows.ui.composition.compositioneffectbrush?view=winrt-22000#remarks
[Win2D is available via cppwinrt]: https://stackoverflow.com/questions/49342164/is-win2d-yet-available-in-c-winrt

View File

@@ -0,0 +1,728 @@
---
author: Mike Griese @zadjii-msft
created on: 2019-12-13
last updated: 2022-04-25
issue id: #3327
---
TODO!S:
* How do themes play with different window title settings? (different themes for different windows. `_quake` esp.))
* any clever ideas for elevated themes?
* Reconcile with global `experimental.useBackgroundImageForWindow` from [#12893]
# Application Theming
## Abstract
This spec outlines how the Windows Terminal will enable users to create custom
"themes" for the application, enabling further customization of the window.
These themes will be implemented as objects containing a group of UI-specific
properties, so users can quickly apply a group of properties atomically.
## Inspiration
Much of the inspiration for this feature comes from VsCode and its themes. These
themes can be more than just different color palettes for the editor - these
themes can control the appearance of a variety of UI elements of the VsCode
window.
## Solution Design
### Requested Functionality ("User Stories")
The following is a long list of ideas of elements of the window that the user
should be able to customize:
* [ ] Pane Border colors (both the background, and the "focused" color) ([#3061])
* [ ] Pane border width ([#3062])
* [ ] Tab _Row_ and _Item_ Background color ([#702]/[#1337]/[#2994]/[#3774]/[#1963])
- Some users want to set these to the accent color
- Some users want to set these to a specific custom color
- Some users want this to use the color straight from the active Terminal,
allowing the tab or titlebar to "blend into" the terminal
* [ ] Feature Request: Setting to hide/remove close ("x") button from tabs ([#3335])
* [ ] Various different tab sizing modes
- the current sizing, which is `SizeToContent`
- Setting a min/max width on tabs
- Configuring tabs to split the available space
Other lower-priority ideas:
* [ ] Enable hiding the tab icon altogether
* [ ] Enable forcing tab icons to monochrome
* [ ] Tab row height
* [ ] Tab row font size, font face
* [ ] Tab corner radius
* [ ] Margin between tabs? Padding within the tab?
* [ ] Left-justify / Center / right-justify tab text, when tabs are wider than
their text?
* [ ] Control colors for light vs dark vs high-contrast modes
* [ ] Enable/disable a shadow underneath the tab row, between tabs and content
* [ ] Enable/disable a shadow cast by terminals on pane borders or a shadow cast
by pane borders on Terminal panes
* [ ] Similarly to the tabs, styling the Status Bar ([#3459])
- Maybe enable it to have the same color as the active TermControl, causing
the same "seamless" effect (see [this
comment](https://github.com/microsoft/terminal/issues/3459#issuecomment-550501577))
- Change font size, face, colors
- Control the borders on the status bar - no top border would give the
impression it's "seamless"
Additionally, the user should be able to easily switch from one installed theme
to another. The user should be able to copy a simple blob of settings from the
web and paste it into their settings to be able to easily try the theme out.
### Difference between "Themes" and "Schemes"
The avid follower of the Windows Terminal might know that the Terminal already
contains support for "color schemes". What makes themes different from these
schemes, and why should they be separate objects?
**Color Schemes** are objects that generally control the appearance of the
Terminal Control itself (the proverbial "black rectangle with text in it").
Primarily, color schemes are used for setting the "color table" of a terminal
instance, setting the values for each of the 16 colors in the terminal's color
table, and the default foreground and background colors. These are properties
that only apply to the contents of the terminal itself, and not necessarily the
entire application. Individual terminal control instances can have different
color schemes. Furthermore, these schemes are largely in-line with schemes
available on other platform's terminals. These schemes were heavily inspired by
the great work done at [iTerm2-Color-Schemes].
Alternatively, **Themes** are sets of properties that apply primarily to the
window of the application itself, but not necessarily the terminal content.
These properties apply globally to the entire window, as opposed to controlling
the appearance of individual terminals. These properties include things such as
the coloration and styling of the tabs in the tab row.
### Theme objects
Themes will be implemented largely similar to the color schemes implementation.
Currently, the terminal contains a list of available color schemes, and profiles
can chose to apply a scheme from the list of schemes. We'll add a list of
`themes`, and globally, the user will be able to specify one of these themes to
apply.
Take for example the following settings excerpt:
```json
{
"theme": "My Boxy Theme",
"themes": [
{
"name": "My Boxy Theme",
"window":{
"applicationTheme": "dark"
},
"tab": {
"radius": 0,
"padding": 5,
"background": "terminalBackground",
"textColor": "key:SystemAccentColorLight3",
"icon": "outline",
"closeButton": "hidden",
},
"tabRow":{
"background": "accent",
"shadows": false
}
},
{
"name": "My small light theme",
"window":{
"applicationTheme": "light"
},
"tab": {
"background": "#80ff0000",
"height": 8,
"icon": "hidden",
"closeButton": "hover"
},
"tabRow":{
"background": "#ffffffff",
"acrylicOpacity": 50,
}
}
]
}
```
In the above settings snippet, we see the following things:
1. A list of `themes` that the user can pick from. Each theme has a `name`
property used to identify the theme, and a group of properties for the theme.
2. The user has set the `theme` to `"My Boxy Theme"`, the first theme
in the list of themes. If the user wanted to switch to the other installed
theme, `"My small light theme"`, they'd simply need to change this property.
> _note_: Initially, we had considered a `elementPropertyName`-like syntax as
opposed to the object-grouped one above. We also considered a
`element.propertyName`-like syntax. Overall, we liked the object based one best.
>
> **For simplicity, we'll be using `element.propertyName` syntax throughout to**
> **refer to these properties, when grouped under `element` objects in the theme.**
These Theme objects are designed to make it simple for the user to be able to
quickly download these as an extension in the future, and hot-switch between
them. Imagine: an application that would provide a gallery of uploaded themes,
and the user could install them as [fragment extensions].
### Exposed theme properties
Themes should be able to control a variety of elements of the Terminal UI. Some
of these settings will be easier to implement than others. As such, below is a
set of properties that seems appropriate to include as part of a "v1" theming
implementation. In [Future Considerations](#future-considerations), we'll
enumerate additional properties that could be added in the future to further
control the UI.
#### Highest priority theming properties
These are the elements that have orders of magnitude more requests:
* Customizing the titlebar color, including the unfocused titlebar color. This
includes merging with the existing `useAcrylicInTabRow` setting.
* Customizing the tab color
* Enabling Mica for the window
These represent the most important asks of theming in the Terminal. Everything
else that follows is merely "nice to have". The most important elements then
are:
* Properties:
- `tab.background`
- `tabRow.background`
- `tabRow.acrylicOpacity`
- `tabRow.unfocusedBackground`
- `window.background.useMica`
* Theme color variants:
- `"#rrggbb"` or `"#rrggbbaa"`
- `"accent"`
- `"terminalBackground"`
#### Additional theming v1 Properties
These are additional settings that seem of higher priority or would be easier to
implement. They are categorized by the element of the Terminal they are
controlling:
##### Individual Tabs
* `tab.cornerRadius`: Control the radius of the corners of the tab items.
Accepts a `double`. If this is set to `0`, then the tabs will have squared-off
corners. No particular limit is set on the max value accepted, though larger
values might not be aesthetically pleasing.
* `tab.bottomCornerRadius`: Control the radius of the bottom corners of the tab
items. This can be used to make the tabs look like "buttons" in the tab row,
instead of tabs.
* `tab.closeButton`: Control the visibility of the close button for a tab item.
Accepts the following values:
- `visible`: The default behavior of the tab item close button - always
visible.
- `hover`: The close button on a tab item only appears when the tab is
hovered.
- `hidden`: The close button on a tab is always hidden.
* `tab.icon`: Control the visibility, appearance of the tab icon
- `visible`: The default behavior of the tab item icon - always visible, and
in full color.
- `outline`: The icon is always visible, but is only drawn as an outline,
using `BitmapIconSource.ShowAsMonochrome(true)`
- `hidden`: The icon is hidden
* `tab.background`: Control the color of the background of tab items. See below
for accepted colors.
##### Tab Row / "Titlebar"
* `tabRow.background`: Control the color of the background of the tab row. When
tabs in the titlebar are enabled, this sets the color of the titlebar. See
below for accepted colors.
- Notably, this is named `tabRow.background`, **not** `titlebar.background`.
Outside of tabs-in-titlebar mode, we can't control the window titlebar
color.
- This ignores any alpha and always uses 1.0 for the alpha channel. See
[Titlebar complications](#Titlebar-complications) for details.
* `tabRow.unfocusedBackground`: Control the color of the background of the tab
row, when the window is unfocused. See below for accepted colors.
- **TODO!** When omitted, should this default to the `tabRow.background`
value (if set), or just the normal unfocused window color? "the normal
unfocused window color" is a SUBSTANTIALLY easier implementation.
- This ignores any alpha and always uses 1.0 for the alpha channel. See
[Titlebar complications](#Titlebar-complications) for details.
* `tabRow.acrylicOpacity`: Optional integer representation of an opacity
(0-100). When provided, the `tabRow.background` color is treated as an acrylic
brush, with the given `TintOpacity`. When omitted, `tabRow.background` is
treated as a solid color.
- This is to replace the original `useAcrylicInTabRow` setting.
- This is NOT provided for the `tabRow.unfocusedBackground` setting. See
[Titlebar complications](#Titlebar-complications) for details.
##### Panes
* `pane.borderColor`: Control the color of the border used to separate panes.
This is the color of the inactive border between panes.
* `pane.activeBorderColor`: Control the color of the border of the active pane
* `pane.borderWidth`: Control the width of the borders used to separate panes.
##### Window Properties
* `window.applicationTheme`: If set, will set the XAML `RequestedTheme`
property. This can be one of `light`, `dark` or `system`. This controls how
XAML fundamentally styles UI elements. If not provided, will use the default
value "system", which will use whatever the system's default theme is.
* `window.roundedCorners`: A boolean, to control whether the window has rounded
corners on Windows 11.
* `window.background.useMica`: a boolean that enables/disables Mica. For more
discussion, see [Mica Spec].
* `window.background.image`: a path to an image to use as the background for the
whole of the content of the Terminal, including in the tab row space.
- Additional properties to control the sizing of this image (`padding`,
`stretchMode`, `opacity`, etc) would also be exposed as
`window.background.imagePadding`, a la the similar Profile settings.
#### Theme Colors
For properties like `tab.background` and `tabRow.background`, these colors can
be one of:
* an `#rrggbb`, `#aarrggbb` color. (Alpha is ignored for `tabRow.background`)
* `accent` for the _titlebar_ version of the accent color. Notably, this is
**not** just some `SystemAccentColor` value, it's apparently some other value.
This has a different value depending on if the window is focused or not. Refer
to Edge the "use accent color on titlebars" setting enabled as a reference.
* `terminalBackground` to use the default background color of the active
terminal instance.
* `terminalForeground` to use the default foreground color of the active
terminal instance.
* `key:SomeXamlKey` to try and look `SomeXamlKey` up from our resources as a
`Color`, and use that color for the value.
- `accent` is NOT the same thing as `key:SystemAccentColor`? If it is, is it a reasonable
alias that we'd want to provide anyways?
- **TODO! DISCUSSION**: PR[#5280] suggested `{ "key": "SomeResourceKey" }` for
string resources, should we use that format for colors like this as well?
This will enable users to not only provide custom colors, but also use the
dynamic color of the active terminal instance as well.
Using `terminalBackground` with multiple concurrent panes with different
backgrounds could certainly lead to some odd behavior. The intention of the
setting is to provide a way for the tab/titlebar to "seamlessly" connect to the
terminal content. However, two panes side-by-side could have different
background colors, which might have an unexpected appearance. Since the user
must have opted in to this behavior, they'll need to decide personally if
that's something that bothers them aesthetically. It's entirely possible that a
user doesn't use panes, and this wouldn't even be a problem for them.
<!-- We could maybe mitigate this by providing the user a way of specifying the
`tab.background` color as having both a "single pane" and "multiple pane" mode,
though I'm not sure I'm in love with this:
```json
"tab.background": {"single": "terminalBackground", "multiple": null},
"tab.background": {"single": "terminalBackground", "multiple": "#ff0000"},
"tab.background": [ "terminalBackground", null ]
```
Also shown is an array based implementation, as an option. Overall I'm not
happy with this, so I think it shouldn't be in the final draft of the spec, but
I'm leaving it for now as an option.
-->
### Implementation of theming
Largely, whenever possible, we should be able to implement this theming support
by modifying our application's `ResourceDictionary` with custom values to
control the appearance of UI elements.
For example, the `TabView` already exposes a number of XAML resources we can
modify to adjust it's appearance.
* `TabViewBackground` controls the appearance of the background of the tab view.
In `showTabsInTitlebar: true` mode, this is the color of the titlebar.
* `TabViewItemHeaderBackground` and `TabViewItemHeaderBackgroundSelected`
control the appearance of an individual tab.
By modifying the values of these brushes, we can control the appearance of the
tabs. So long as we only in-place modify the resources, XAML is smart enough to
be able to update it's appearance automatically. We can do this by querying the
`ResourceDictionary` for a given resource, and changing it's value, rather than
`insert`ing a new value into the `ResourceDictionary` to replace the old one.
In addition to the above properties, I propose adding a couple of our own
properties: `PaneBorderWidth`: To control the width of pane borders
`PaneBorderBrush`: To control the appearance of _inactive_ pane borders
`ActivePaneBorderBrush`: To control the appearance of _active_ pane borders
In order to respond to the live-updating of the `TermControl`'s background
color, we'll need to add some more specific logic beyond simply updating a XAML
resource when settings change. Whenever a `TermControl`'s background color
changes, or the active pane in a tab changes:
* If `tab.background == "terminalBackground"`:
- If this control is the tab's active terminal control (and the tab doesn't
have a custom color set by the color picker), update the tab's own
`TabViewItem` with updated `TabViewItemHeaderBackground` and
`TabViewItemHeaderBackgroundSelected` values.
- Here, we _don't_ want to update the `App`'s resources, since those
apply globally, and each tab might have a control with a different
color.
- The color set by the color picker should override the color from the
theme (as the former is a run-time property set to override the
latter).
* If `tabRow.background == "terminalBackground"`:
- If this control is the active terminal of the active `Tab`, then we need
to raise an event to communicate this updated value up to the window
layer. We'll raise a `"TabRowBackgroundBrush"` property changed event,
that the app host can listen for and use to set the titlebar's color, if
needed.
- The `TerminalPage` also will need to set the Background of the
`TabRowControl` to match.
The `tab.cornerRadius` might be a bit trickier to implement. Currently, there's
not a XAML resource that controls this, nor is this something that's exposed by
the TabView control. Fortunately, this is something that's exposed to us
programmatically. We'll need to manually set that value on each `TabViewItem` as
we create new tabs. When we reload settings, we'll need to make sure to come
through and update those values manually.
> NOTE: [microsoft-ui-xaml#2201] suggested that this will be possible with a
> future MUX version and changing the `OverlayCornerRadius`.
### Tab Background Color, Overline Color, and the Tab Color Picker
Concurrently with the writing of this spec, work is being done to add a "color
picker" for tabs, that lets the user manually set a background color for tabs.
This may in the future cause some complications with setting a color for tabs
from the theme.
When both features are combined, the color set at runtime but the color picker
should override whatever color the user has set in the theme. When the color
picker "clears" the color it has set for the tab, it should revert to the color
from the theme (if one is set).
Also mentioned in the implementation of the color picker feature was the ability
to not set the entire color of the tab, but just the color of a tab "overline",
similar to the way Firefox (by default) styles the focused tab.
Currently, the `TabView` doesn't support a tab "overline" like this, however, in
the future where this is possible, we'd love to also support such an overline.
However, the story of setting the tab color manually becomes a bit more
confusing now.
* The user should be able to set both the `tab.background` and `tab.overline`
colors in a theme.
* The user should be able to configure whether the color picker sets the
`background` or the `overline` color of the tab.
The second setting added above will allow the user to change what's controlled
by the color picker. Similarly to how the color picker can set the background of
the tab to override the background from the theme, the user could configure the
color picker to be able to change the overline color, not the background color
of the tab. Then, when the user uses the color picker, the overline color will
be overridden by the color picker, instead of the tab background color.
**Other things to consider:**
* Users might want to be able to set a tab color as a part of the profile. One
could imagine wanting to set the tab background color for Windows PowerShell
to `rgb(1, 36, 86)` automatically. If we make this property part of the
Profile, then we should use the profile's value as the runtime-override (of
the theme value) for this property. If the color picker is used to set the
color of the tab, then it'll override the runtime color for that tab.
- How does this interact with multiple Panes in a tab? Should the Tab
override color be per-terminal instance? If the terminal has a tab color,
then that would override the theme, but not the tab's own override color?
- If that were the case, the order of precedence would be:
1. A color set at runtime with the color picker
2. A color from the active terminal within the tab, if it has one
3. The tab color from the theme
* Users might want to be able to configure the titlebar to use a color based off
the active tab color. We might need an additional special value like
`terminalBackground` that lets users say "I want to use the active tab color
as the titlebar color".
- During [#3789], there was a point where the terminal raised actually
implemented something like this. In it's implementation, the titlebar color
would be slightly lighter or darker than the tab color (to provide some
contrast). We'd want to make sure that the user could specify both "I want
to use the tab color with some contrast applied" or just literally "Use
whatever the active tab's color is."
### Default Themes
Late in 1.0, we renamed the old property `requestedTheme` to just `theme`.
Currently, the user can use that property to simply set the XAML
`RequestedTheme` property, which controls the theming of all the XAML UI
elements. Currently, they can set that value to one of `light`, `dark` or
`system`.
To maintain backwards compatibility with that setting, we'll introduce _three_
themes to `defaults.json`:
```json
"themes": [
{
"name": "light",
"window":{
"applicationTheme": "light"
},
},
{
"name": "dark",
"window":{
"applicationTheme": "dark"
},
},
{
"name": "system",
"window":{
"applicationTheme": "system"
},
}
]
```
Each of these themes will only define one property by default: the
`window.applicationTheme` property, which is now responsible for setting the
XAML `RequestedTheme` property. With these default themes, the user will still
be able to use the old names seamlessly to get the same behavior.
Additionally, the user will NOT be able to override these built-in themes.
Experience trying to not serialize the default color schemes has proven
exceptionally tricky, so we're not going to allow that for the built-in themes.
The user will always need to fork them to create a new theme. If they're found
in the user settings file, we'll just ignore them.
## UI/UX Design
[TODO!]: # TODO: We should include more mockups here. That would be nice.
![Tab matches Terminal background](Tab-Matches-Terminal-Color-000.png)
_fig 1_: Using a tab color set to "terminalBackground". The Windows PowerShell
tab has also set its color with the color picker.
![Acrylic in the titlebar](AcrylicInTitlebar.png)
_fig 2_: Using an acrylic titlebar color, with a tab color set to
"terminalBackground"
![Titlebar matches Terminal background](AcrylicTerminalBackgroundInTitlebar.png)
_fig 3_: Using an acrylic terminal background, and the titlebar color is set to
"terminalBackground"
![Whole window background image](whole-window-background-000.png) _fig
4_: Using a single image as the background for the window, with a transparent
tab row, and rounded bottoms on the TabViewItems. Courtesy of
[@Shomnipotence](https://github.com/microsoft/terminal/issues/3327#issuecomment-765493313)
![Tabs with bottom corner radius set](tab-buttons-000.png) _fig
5_: Using a bottom corner radius to make tabs appear like buttons on the tab row. Courtesy of
[@simioni](https://github.com/microsoft/terminal/issues/3774#issuecomment-609408305)
[TODO!]: # TODO: Settings UI mocks? These pretty substantially affect the UI.
<!-- We probably need to expose them in the UI in some way, and not just leave them as "power user settings" -->
## Potential Issues
It's totally possible for the user to set some sort of theme that just looks
bad. This is absolutely a "beauty in the eye of the beholder" situation - not
everyone is going to like the appearance of every theme. The goal of the
Terminal is to provide a basic theme that's appropriate for anyone, but empower
users to customize the terminal however they see fit. If the user chooses a
theme that's not particularly appealing, they can always change it back.
### Accessibility
For people using the default theming, there should not be any particular
regressions. However, this change does open up the Terminal to changes that
might make the Terminal less accessible with certain theme configurations. As
these themes would all be user-defined and controlled by the user, we're not
concerned that this will be much of an issue. If a user finds one of their
themes is less accessible, they can always change the theme to be more
appropriate for them, or even switch to another theme.
Furthermore, this might _help_ certain accessibility stories. Users could pick
themes with _even more_ contrast than the Terminal provides by default, or
larger font sizes, which might help make parts of the Terminal _more_ visible
than the default UI.
### Security
This should not introduce any _new_ security concerns. We're relying on the
security of jsoncpp for parsing json. Adding new keys to the settings file
will rely on jsoncpp's ability to securely parse those json values.
### Reliability
This change should not have any particular reliability concerns.
### Compatibility
The biggest compatibility concern is regarding the existing values for the
`theme` property, which is addressed above.
#### `useAcrylicInTabRow` migration
[TODO!]: # TODO: Deprecating the current titlebar acrylic setting, or totally overriding in theme.
#### `experimental.useBackgroundImageForWindow` migration
[TODO!]: # TODO: Deprecating the current setting or migrating or whatever
### Performance, Power, and Efficiency
This change should not have any particular performance concerns. Additional
acrylic usage might impact battery life. There's not much concern for any
substantial new impacts, however.
### Branding
Are we concerned that by enabling theming, the appearance of the Terminal won't
be as static, and won't necessarily have as specific a look? It might be harder
for potential users see a screenshot of the Terminal and _know_ "Thats the
Windows Terminal". Is this something we're really all that concerned about
though? If this is something users want (it is), then shouldn't that be what
matters?
### Titlebar complications
Unfortunately, the original User32 titlebar is actually always drawn underneath
our titlebar. Even when the tabs are in the titlebar, that's actually just XAML
content drawn on top of the original frame. The rest of the window is
transparent, but the titlebar is there.
Our design to enable unfocused acrylic to work relies on in-app acrylic to allow
the acrylic to blur with the transparent window contents. However, since the
User32 titlebar is always there, in-app acrylic would end up always blurring
_the original titlebar_, which looks ridiculous. This means we can't have
unfocused acrylic without showing that titlebar. We'd rather remove that
foot gun, and make it explicit that this setting does not exist.
### Light & dark mode theming
One request that comes up with frequency is the ability to change the color
scheme of a profile automatically based on the system theme. Many users have
scripts that automatically change between light and dark theme in the OS based
on time of day.
One thing this design does not do well is account for such theme-switching
scenarios. This design assumes a static set of colors for a whole Terminal
theme, regardless of whatever `window.applicationTheme` is set to. Should the
user leave `window.applicationTheme` set to `system`, it's entirely likely that
they would like the rest of their colors to automatically update to match.
To address this, we'll allow the window-level `theme` property to not only allow
a string for a name-based lookup in the list of themes, but als an object. That
object will accept two properties: `light` and `dark`. Each of these accepts a
string representing the name of a theme to use for that specific OS theme. These
strings will default to `"light"` and `"dark"` respectively.
```jsonc
{
"theme": {
"light": "my light theme",
"dark": "my dark theme"
}
}
```
<!-- Also considered: allow the user to set their own brushes as part of a theme, like:
```jsonc
{
"name": "My theme aware theme",
"brushes": {
"light": {
"Foo": "#ff0000"
},
"dark": {
"Foo": "#00ff00"
}
},
"window.applicationTheme": "system",
"tabRow.background": "key:Foo",
}
```
This seemed far too complicated to actually understand. -->
### Admin window themes
[TODO!]: # TODO! Any clever ideas?
Same idea as the light vs dark mode theme ideas. How should users be able to
style admin vs regular windows?
## Addenda
This spec also has a follow-up spec which elaborates on the complexities of Mica
in the Terminal. Please also refer to:
* [Mica in the Terminal]
## Future considerations
* Mentioned in [#7005] was the idea of shipping a default theme that had values
aligned with the appearance of the Edge browser. Perhaps something like:
```jsonc
{
"name": "Edge",
"window":{
"applicationTheme": "system"
},
"tab": {
"background": "#whatever-color-edge-is" // Might need a "key:" resource here for light/dark theme switching
},
"tabRow":{
"background": "accent",
}
},
```
* Applications should be able to install themes as fragments.
- We probably shouldn't allow layering for fragment themes - don't want
`foo.exe` installing a `light` theme that totally overrides the built-in
one. Right? **TODO! DISCUSSION**
* ~I don't think it's unreasonable to implement support for `theme` as either a
string or an object. If `theme` is a string, then we can do a name-based
lookup in a table of themes. If it's an object, we can just use that object
immediately. Doing this might provide a simpler implementation plan whereby we
allow `"default"|"light"|"dark"|{object}` at first, and then later add the
list of themes.~
- This was a cool idea, but ultimately discarded in favor of the OS light/dark
theme switching, which needed the object version of `theme` to be reserved
for the OS mode lookup.
* A cool idea from discussion: `window.highContrastSchemes` as a theme member
that controls a per-control property. This would override the color scheme of
any pane with a high contrast version, ignoring any colors emitted by the
client application. Details are left for a future spec.
#### Theming v2 Properties
* `tab.padding`: Control the padding _within_ a tab between the text and the
"sides" of the tab
* `tab.textColor`: Change the color of the text on a tab
* `tabRow.shadows`: Enable/disable the tab "shadows"
- note that they're enabled by default and already nearly impossible to see in
dark mode.
* `tabRow.height`: Change the height of the tab row.
* `tabRow.underlineHeight`: Controls the height of a border placed between the
tab row and the Terminal panes beneath it. This border doesn't exist
currently.
* `tabRow.underlineColor`: Controls the color of the aforementioned underline
* `window.frameColor`: The `DWMWA_BORDER_COLOR` DWM attribute is [SUPER fun to
play with], and trivial to set. We should definitely exposed it.
<!-- Footnotes -->
[iTerm2-Color-Schemes]: https://github.com/mbadolato/iTerm2-Color-Schemes
[#3061]: https://github.com/microsoft/terminal/issues/3061
[#3062]: https://github.com/microsoft/terminal/issues/3062
[#702]: https://github.com/microsoft/terminal/issues/702
[#1337]: https://github.com/microsoft/terminal/issues/1337
[#2994]: https://github.com/microsoft/terminal/issues/2994
[#3774]: https://github.com/microsoft/terminal/issues/3774
[#3789]: https://github.com/microsoft/terminal/pull/3789
[#1963]: https://github.com/microsoft/terminal/issues/1963
[#3335]: https://github.com/microsoft/terminal/issues/3335
[#3459]: https://github.com/microsoft/terminal/issues/3459
[#7005]: https://github.com/microsoft/terminal/issues/7005
[#5280]: https://github.com/microsoft/terminal/pull/5280
[microsoft-ui-xaml#2201]: https://github.com/microsoft/microsoft-ui-xaml/pull/2201#issuecomment-606888293
[#12893]: https://github.com/microsoft/terminal/pull/12893
[Mica in the Terminal]: ./%2310509%20-%20Mica.md
[Mica Spec]: ./%2310509%20-%20Mica.md
[SUPER fun to play with]: https://github.com/microsoft/terminal/issues/12950
[fragment extensions]: https://docs.microsoft.com/en-us/windows/terminal/json-fragment-extensions

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 779 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

View File

@@ -114,7 +114,7 @@ The jumplist will have to be saved each time a profile change occurs but the fre
#### Should it open a new instance of the terminal or open in a new tab?
#### What should happen if a non existent profile is launched
#### What should happen if a nonexistent profile is launched
The jumplist is only updated when the application is running so the profiles could be modified or deleted outside and the jumplist will not be updated. Handling will be done by whatever handles the command line parsing.
## Future considerations

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
<Import Project="$(OpenConsoleDir)src\wap-common.build.pre.props" />
<PropertyGroup Label="Configuration">
@@ -87,10 +87,6 @@
Since PRI file generation is _before_ manifest generation (for possibly obvious or
important reasons), that doesn't work for us.
-->
<PropertyGroup>
<!-- Only for MSBuild versions < 16.3.0 -->
<_GenerateProjectPriFileDependsOn Condition="$(MSBuildVersion) &lt; '16.3.0'">OpenConsoleLiftDesktopBridgePriFiles;$(_GenerateProjectPriFileDependsOn)</_GenerateProjectPriFileDependsOn>
</PropertyGroup>
<Target Name="OpenConsoleLiftDesktopBridgePriFiles" DependsOnTargets="_ConvertItems">
<ItemGroup>
<_PriFile Include="@(_NonWapProjProjectOutput)" Condition="'%(Extension)' == '.pri'" />

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<ProjectGuid>{a4394404-37f7-41c1-802b-49788d3720e3}</ProjectGuid>
<Keyword>Win32Proj</Keyword>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<ProjectGuid>{26c51792-41a3-4fe0-ab5e-8b69d557bf91}</ProjectGuid>
<ProjectName>SampleApp</ProjectName>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" />
<PropertyGroup Label="Globals">

View File

@@ -1,20 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="Console Rules" Description="These rules enforce static analysis on console code." ToolsVersion="15.0">
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="Console Rules" Description="These rules enforce static analysis on console code." ToolsVersion="17.0">
<Include Path="cppcorecheckrules.ruleset" Action="Error" />
<Rules AnalyzerId="Microsoft.Analyzers.NativeCodeAnalysis" RuleNamespace="Microsoft.Rules.Native">
<Rule Id="C6001" Action="Error" />
<Rule Id="C6011" Action="Error" />
<Rules AnalyzerId="Microsoft.Analyzers.NativeCodeAnalysis" RuleNamespace="Microsoft.Rules.Native">
<Rule Id="C6001" Action="Error" />
<Rule Id="C6011" Action="Error" />
<!-- We can't do dynamic cast because RTTI is off. -->
<!-- RTTI is off because Windows OS policies believe RTTI has too much binary size impact for the value and is less portable than RTTI-off modules. -->
<Rule Id="C26466" Action="None" />
<!-- This one has caught us off guard as it suddenly showed up. Re-enablement is going to be in #2941 -->
<Rule Id="C26814" Action="None" />
<!-- There are *so many* enums that should be enum classes. -->
<Rule Id="C26812" Action="None" />
</Rules>
</RuleSet>

View File

@@ -1,27 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{9cf74355-f018-4c19-81ad-9dc6b7f2c6f5}</ProjectGuid>
<RootNamespace>apimswincoresynchl120</RootNamespace>
<ConfigurationType>DynamicLibrary</ConfigurationType>
</PropertyGroup>
<Import Project="$(SolutionDir)src\common.build.pre.props" />
<ItemGroup>
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="definitions.def" />
</ItemGroup>
<Import Project="$(SolutionDir)src\common.build.post.props" />
<ItemDefinitionGroup>
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
<Link>
<AdditionalDependencies>kernel32.lib</AdditionalDependencies>
<ModuleDefinitionFile>definitions.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
</Project>

View File

@@ -1,30 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Natvis Include="$(SolutionDir)tools\ConsoleTypes.natvis" />
</ItemGroup>
<ItemGroup>
<None Include="definitions.def">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
</Project>

View File

@@ -1,19 +0,0 @@
LIBRARY
EXPORTS
DeleteSynchronizationBarrier = kernel32.DeleteSynchronizationBarrier
EnterSynchronizationBarrier = kernel32.EnterSynchronizationBarrier
InitOnceBeginInitialize = kernel32.InitOnceBeginInitialize
InitOnceComplete = kernel32.InitOnceComplete
InitOnceExecuteOnce = kernel32.InitOnceExecuteOnce
InitOnceInitialize = kernel32.InitOnceInitialize
InitializeConditionVariable = kernel32.InitializeConditionVariable
InitializeSynchronizationBarrier = kernel32.InitializeSynchronizationBarrier
SignalObjectAndWait = kernel32.SignalObjectAndWait
Sleep = kernel32.Sleep
SleepConditionVariableCS = kernel32.SleepConditionVariableCS
SleepConditionVariableSRW = kernel32.SleepConditionVariableSRW
WaitOnAddress
WakeAllConditionVariable = kernel32.WakeAllConditionVariable
WakeByAddressAll
WakeByAddressSingle
WakeConditionVariable = kernel32.WakeConditionVariable

View File

@@ -1,189 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
// The code in this file was adapted from the STL on the 2021-07-05. Commit:
// https://github.com/microsoft/STL/blob/e745bad3b1d05b5b19ec652d68abb37865ffa454/stl/src/atomic_wait.cpp
//
// It backports the following Windows 8 functions to Windows 7:
// * WaitOnAddress
// * WakeByAddressSingle
// * WakeByAddressAll
//
#include <cstdint>
#include <new>
#include <winsdkver.h>
#define _WIN32_WINNT 0x0601
#include <sdkddkver.h>
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <Windows.h>
#include <intrin.h>
namespace
{
class [[nodiscard]] SRWLockGuard
{
public:
explicit SRWLockGuard(SRWLOCK& lock) noexcept :
_lock(&lock)
{
AcquireSRWLockExclusive(_lock);
}
~SRWLockGuard()
{
ReleaseSRWLockExclusive(_lock);
}
SRWLockGuard(const SRWLockGuard&) = delete;
SRWLockGuard& operator=(const SRWLockGuard&) = delete;
SRWLockGuard(SRWLockGuard&&) = delete;
SRWLockGuard& operator=(SRWLockGuard&&) = delete;
private:
SRWLOCK* _lock;
};
struct WaitContext
{
const volatile void* address;
WaitContext* next;
WaitContext* prev;
CONDITION_VARIABLE cv;
};
struct [[nodiscard]] GuardedWaitContext : WaitContext
{
GuardedWaitContext(const volatile void* storage, WaitContext* head) noexcept :
WaitContext{ storage, head, head->prev, CONDITION_VARIABLE_INIT }
{
prev->next = this;
next->prev = this;
}
~GuardedWaitContext()
{
const auto n = next;
const auto p = prev;
next->prev = p;
prev->next = n;
}
GuardedWaitContext(const GuardedWaitContext&) = delete;
GuardedWaitContext& operator=(const GuardedWaitContext&) = delete;
GuardedWaitContext(GuardedWaitContext&&) = delete;
GuardedWaitContext& operator=(GuardedWaitContext&&) = delete;
};
#pragma warning(push)
#pragma warning(disable : 4324) // structure was padded due to alignment specifier
struct alignas(std::hardware_destructive_interference_size) WaitTableEntry
{
SRWLOCK lock = SRWLOCK_INIT;
WaitContext head = { nullptr, &head, &head, CONDITION_VARIABLE_INIT };
};
#pragma warning(pop)
[[nodiscard]] WaitTableEntry& GetWaitTableEntry(const volatile void* const storage) noexcept
{
// A prime number for the hash table size was chosen to prevent collisions.
constexpr size_t size = 251;
constexpr std::hash<uintptr_t> hasher;
static WaitTableEntry table[size];
#pragma warning(suppress : 26446) // Prefer to use gsl::at() instead of unchecked subscript operator
#pragma warning(suppress : 26482) // Only index into arrays using constant expressions
#pragma warning(suppress : 26490) // Don't use reinterpret_cast
return table[hasher(reinterpret_cast<uintptr_t>(storage)) % size];
}
#pragma warning(suppress : 26429) // Symbol 'comparand' is never tested for nullness, it can be marked as not_null
bool AreEqual(const volatile void* storage, const void* comparand, size_t size) noexcept
{
switch (size)
{
case 1:
return __iso_volatile_load8(static_cast<const volatile __int8*>(storage)) == *static_cast<const __int8*>(comparand);
case 2:
return __iso_volatile_load16(static_cast<const volatile __int16*>(storage)) == *static_cast<const __int16*>(comparand);
case 4:
return __iso_volatile_load32(static_cast<const volatile __int32*>(storage)) == *static_cast<const __int32*>(comparand);
case 8:
return __iso_volatile_load64(static_cast<const volatile __int64*>(storage)) == *static_cast<const __int64*>(comparand);
default:
abort();
}
}
} // unnamed namespace
extern "C" BOOL WINAPI WaitOnAddress(_In_reads_bytes_(AddressSize) volatile VOID* Address, _In_reads_bytes_(AddressSize) PVOID CompareAddress, _In_ SIZE_T AddressSize, _In_opt_ DWORD dwMilliseconds)
{
auto& entry = GetWaitTableEntry(Address);
SRWLockGuard guard{ entry.lock };
GuardedWaitContext context{ Address, &entry.head };
for (;;)
{
// NOTE: under lock to prevent lost wakes
if (!AreEqual(Address, CompareAddress, AddressSize))
{
return TRUE;
}
if (!SleepConditionVariableSRW(&context.cv, &entry.lock, dwMilliseconds, 0))
{
#ifndef NDEBUG
if (GetLastError() != ERROR_TIMEOUT)
{
abort();
}
#endif
return FALSE;
}
if (dwMilliseconds != INFINITE)
{
// spurious wake to recheck the clock
return TRUE;
}
}
}
extern "C" VOID WINAPI WakeByAddressSingle(_In_ PVOID Address)
{
auto& entry = GetWaitTableEntry(Address);
SRWLockGuard guard(entry.lock);
for (auto context = entry.head.next; context != &entry.head; context = context->next)
{
if (context->address == Address)
{
// Can't move wake outside SRWLOCKed section: SRWLOCK also protects the context itself
WakeAllConditionVariable(&context->cv);
// This break; is the difference between WakeByAddressSingle and WakeByAddressAll
break;
}
}
}
extern "C" VOID WINAPI WakeByAddressAll(_In_ PVOID Address)
{
auto& entry = GetWaitTableEntry(Address);
SRWLockGuard guard(entry.lock);
for (auto context = entry.head.next; context != &entry.head; context = context->next)
{
if (context->address == Address)
{
// Can't move wake outside SRWLOCKed section: SRWLOCK also protects the context itself
WakeAllConditionVariable(&context->cv);
}
}
}

View File

@@ -5,55 +5,30 @@
#include "MidiAudio.hpp"
#include "../terminal/parser/stateMachine.hpp"
namespace
{
class MidiOut
{
public:
static constexpr auto NOTE_OFF = 0x80;
static constexpr auto NOTE_ON = 0x90;
static constexpr auto PROGRAM_CHANGE = 0xC0;
#include <dsound.h>
// We're using a square wave as an approximation of the sound that the
// original VT525 terminals might have produced. This is probably not
// quite right, but it works reasonably well.
static constexpr auto SQUARE_WAVE_SYNTH = 80;
MidiOut() noexcept
{
if constexpr (Feature_DECPSViaMidiPlayer::IsEnabled())
{
midiOutOpen(&handle, MIDI_MAPPER, NULL, NULL, CALLBACK_NULL);
OutputMessage(PROGRAM_CHANGE, SQUARE_WAVE_SYNTH);
}
}
~MidiOut() noexcept
{
if constexpr (Feature_DECPSViaMidiPlayer::IsEnabled())
{
midiOutClose(handle);
}
}
void OutputMessage(const int b1, const int b2, const int b3 = 0, const int b4 = 0) noexcept
{
if constexpr (Feature_DECPSViaMidiPlayer::IsEnabled())
{
midiOutShortMsg(handle, MAKELONG(MAKEWORD(b1, b2), MAKEWORD(b3, b4)));
}
}
MidiOut(const MidiOut&) = delete;
MidiOut(MidiOut&&) = delete;
MidiOut& operator=(const MidiOut&) = delete;
MidiOut& operator=(MidiOut&&) = delete;
private:
HMIDIOUT handle = nullptr;
};
}
#pragma comment(lib, "dxguid.lib")
#pragma comment(lib, "dsound.lib")
using Microsoft::WRL::ComPtr;
using namespace std::chrono_literals;
// The WAVE_DATA below is an 8-bit PCM encoding of a triangle wave form.
// We just play this on repeat at varying frequencies to produce our notes.
constexpr auto WAVE_SIZE = 16u;
constexpr auto WAVE_DATA = std::array<byte, WAVE_SIZE>{ 128, 159, 191, 223, 255, 223, 191, 159, 128, 96, 64, 32, 0, 32, 64, 96 };
MidiAudio::MidiAudio(HWND windowHandle)
{
if (SUCCEEDED(DirectSoundCreate8(nullptr, &_directSound, nullptr)))
{
if (SUCCEEDED(_directSound->SetCooperativeLevel(windowHandle, DSSCL_NORMAL)))
{
_createBuffers();
}
}
}
MidiAudio::~MidiAudio() noexcept
{
try
@@ -61,7 +36,7 @@ MidiAudio::~MidiAudio() noexcept
#pragma warning(suppress : 26447)
// We acquire the lock here so the class isn't destroyed while in use.
// If this throws, we'll catch it, so the C26447 warning is bogus.
_inUseMutex.lock();
const auto lock = std::unique_lock{ _inUseMutex };
}
catch (...)
{
@@ -103,13 +78,26 @@ void MidiAudio::Unlock()
void MidiAudio::PlayNote(const int noteNumber, const int velocity, const std::chrono::microseconds duration) noexcept
try
{
// The MidiOut is a local static because we can only have one instance,
// and we only want to construct it when it's actually needed.
static MidiOut midiOut;
if (velocity)
const auto& buffer = _buffers.at(_activeBufferIndex);
if (velocity && buffer)
{
midiOut.OutputMessage(MidiOut::NOTE_ON, noteNumber, velocity);
// The formula for frequency is 2^(n/12) * 440Hz, where n is zero for
// the A above middle C (A4). In MIDI terms, A4 is note number 69,
// which is why we subtract 69. We also need to multiply by the size
// of the wave form to determine the frequency that the sound buffer
// has to be played to achieve the equivalent note frequency.
const auto frequency = std::pow(2.0, (noteNumber - 69.0) / 12.0) * 440.0 * WAVE_SIZE;
buffer->SetFrequency(gsl::narrow_cast<DWORD>(frequency));
// For the volume, we're using the formula defined in the General
// MIDI Level 2 specification: Gain in dB = 40 * log10(v/127). We need
// to multiply by 4000, though, because the SetVolume method expects
// the volume to be in hundredths of a decibel.
const auto volume = 4000.0 * std::log10(velocity / 127.0);
buffer->SetVolume(gsl::narrow_cast<LONG>(volume));
// Resetting the buffer to a position that is slightly off from the
// last position will help to produce a clearer separation between
// tones when repeating sequences of the same note.
buffer->SetCurrentPosition((_lastBufferPosition + 12) % WAVE_SIZE);
}
// By waiting on the shutdown future with the duration of the note, we'll
@@ -117,9 +105,48 @@ try
// of the wait early if we've been shutdown.
_shutdownFuture.wait_for(duration);
if (velocity)
if (velocity && buffer)
{
midiOut.OutputMessage(MidiOut::NOTE_OFF, noteNumber, velocity);
// When the note ends, we just turn the volume down instead of stopping
// the sound buffer. This helps reduce unwanted static between notes.
buffer->SetVolume(DSBVOLUME_MIN);
buffer->GetCurrentPosition(&_lastBufferPosition, nullptr);
}
// Cycling between multiple buffers can also help reduce the static.
_activeBufferIndex = (_activeBufferIndex + 1) % _buffers.size();
}
CATCH_LOG()
void MidiAudio::_createBuffers() noexcept
{
auto waveFormat = WAVEFORMATEX{};
waveFormat.wFormatTag = WAVE_FORMAT_PCM;
waveFormat.nChannels = 1;
waveFormat.nSamplesPerSec = 8000;
waveFormat.wBitsPerSample = 8;
waveFormat.nBlockAlign = waveFormat.nChannels * waveFormat.wBitsPerSample / 8;
waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign;
auto bufferDescription = DSBUFFERDESC{};
bufferDescription.dwSize = sizeof(DSBUFFERDESC);
bufferDescription.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY | DSBCAPS_GLOBALFOCUS;
bufferDescription.dwBufferBytes = WAVE_SIZE;
bufferDescription.lpwfxFormat = &waveFormat;
for (auto& buffer : _buffers)
{
if (SUCCEEDED(_directSound->CreateSoundBuffer(&bufferDescription, &buffer, nullptr)))
{
LPVOID bufferPtr;
DWORD bufferSize;
if (SUCCEEDED(buffer->Lock(0, 0, &bufferPtr, &bufferSize, nullptr, nullptr, DSBLOCK_ENTIREBUFFER)))
{
std::memcpy(bufferPtr, WAVE_DATA.data(), WAVE_DATA.size());
buffer->Unlock(bufferPtr, bufferSize, nullptr, 0);
}
buffer->SetVolume(DSBVOLUME_MIN);
buffer->Play(0, 0, DSBPLAY_LOOPING);
}
}
}

View File

@@ -11,13 +11,17 @@ Abstract:
#pragma once
#include <array>
#include <future>
#include <mutex>
struct IDirectSound8;
struct IDirectSoundBuffer;
class MidiAudio
{
public:
MidiAudio() = default;
MidiAudio(HWND windowHandle);
MidiAudio(const MidiAudio&) = delete;
MidiAudio(MidiAudio&&) = delete;
MidiAudio& operator=(const MidiAudio&) = delete;
@@ -30,6 +34,12 @@ public:
void PlayNote(const int noteNumber, const int velocity, const std::chrono::microseconds duration) noexcept;
private:
void _createBuffers() noexcept;
Microsoft::WRL::ComPtr<IDirectSound8> _directSound;
std::array<Microsoft::WRL::ComPtr<IDirectSoundBuffer>, 2> _buffers;
size_t _activeBufferIndex = 0;
DWORD _lastBufferPosition = 0;
std::promise<void> _shutdownPromise;
std::future<void> _shutdownFuture;
std::mutex _inUseMutex;

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{3c67784e-1453-49c2-9660-483e2cc7f7ad}</ProjectGuid>
<Keyword>Win32Proj</Keyword>

View File

@@ -357,11 +357,6 @@ void TextAttribute::SetReverseVideo(bool isReversed) noexcept
WI_UpdateFlag(_wAttrLegacy, COMMON_LVB_REVERSE_VIDEO, isReversed);
}
ExtendedAttributes TextAttribute::GetExtendedAttributes() const noexcept
{
return _extendedAttrs;
}
// Routine Description:
// - swaps foreground and background color
void TextAttribute::Invert() noexcept

View File

@@ -109,7 +109,10 @@ public:
void SetOverlined(bool isOverlined) noexcept;
void SetReverseVideo(bool isReversed) noexcept;
ExtendedAttributes GetExtendedAttributes() const noexcept;
constexpr ExtendedAttributes GetExtendedAttributes() const noexcept
{
return _extendedAttrs;
}
bool IsHyperlink() const noexcept;
@@ -161,6 +164,13 @@ public:
{
return WI_IsAnyFlagSet(_wAttrLegacy, COMMON_LVB_GRID_HORIZONTAL | COMMON_LVB_GRID_LVERTICAL | COMMON_LVB_GRID_RVERTICAL | COMMON_LVB_UNDERSCORE);
}
constexpr bool HasAnyExtendedAttributes() const noexcept
{
return GetExtendedAttributes() != ExtendedAttributes::Normal ||
IsAnyGridLineEnabled() ||
GetHyperlinkId() != 0 ||
IsReverseVideo();
}
private:
static std::array<TextColor, 16> s_legacyForegroundColorMap;

View File

@@ -12,20 +12,8 @@
// Arguments:
// - ulSize - The height of the cursor within this buffer
Cursor::Cursor(const ULONG ulSize, TextBuffer& parentBuffer) noexcept :
_parentBuffer{ parentBuffer },
_fHasMoved(false),
_fIsVisible(true),
_fIsOn(true),
_fIsDouble(false),
_fBlinkingAllowed(true),
_fDelay(false),
_fIsConversionArea(false),
_fIsPopupShown(false),
_fDelayedEolWrap(false),
_fDeferCursorRedraw(false),
_fHaveDeferredCursorRedraw(false),
_ulSize(ulSize),
_cursorType(CursorType::Legacy)
_parentBuffer{ &parentBuffer },
_ulSize(ulSize)
{
}
@@ -185,7 +173,7 @@ void Cursor::_RedrawCursorAlways() noexcept
{
try
{
_parentBuffer.TriggerRedrawCursor(_cPosition);
_parentBuffer->TriggerRedrawCursor(_cPosition);
}
CATCH_LOG();
}

View File

@@ -27,6 +27,7 @@ public:
// the following values are used to create the textmode cursor.
static constexpr unsigned int CURSOR_SMALL_SIZE = 25; // large enough to be one pixel on a six pixel font
Cursor() noexcept = default;
Cursor(const ULONG ulSize, TextBuffer& parentBuffer) noexcept;
~Cursor();
@@ -84,7 +85,7 @@ public:
void SetType(const CursorType type) noexcept;
private:
TextBuffer& _parentBuffer;
TextBuffer* _parentBuffer = nullptr;
//TODO: separate the rendering and text placement
@@ -92,25 +93,25 @@ private:
til::point _cPosition; // current position on screen (in screen buffer coords).
bool _fHasMoved;
bool _fIsVisible; // whether cursor is visible (set only through the API)
bool _fIsOn; // whether blinking cursor is on or not
bool _fIsDouble; // whether the cursor size should be doubled
bool _fBlinkingAllowed; //Whether or not the cursor is allowed to blink at all. only set through VT (^[[?12h/l)
bool _fDelay; // don't blink scursor on next timer message
bool _fIsConversionArea; // is attached to a conversion area so it doesn't actually need to display the cursor.
bool _fIsPopupShown; // if a popup is being shown, turn off, stop blinking.
bool _fHasMoved = false;
bool _fIsVisible = true; // whether cursor is visible (set only through the API)
bool _fIsOn = true; // whether blinking cursor is on or not
bool _fIsDouble = false; // whether the cursor size should be doubled
bool _fBlinkingAllowed = true; //Whether or not the cursor is allowed to blink at all. only set through VT (^[[?12h/l)
bool _fDelay = false; // don't blink scursor on next timer message
bool _fIsConversionArea = false; // is attached to a conversion area so it doesn't actually need to display the cursor.
bool _fIsPopupShown = false; // if a popup is being shown, turn off, stop blinking.
bool _fDelayedEolWrap; // don't wrap at EOL till the next char comes in.
bool _fDelayedEolWrap = false; // don't wrap at EOL till the next char comes in.
til::point _coordDelayedAt; // coordinate the EOL wrap was delayed at.
bool _fDeferCursorRedraw; // whether we should defer redrawing the cursor or not
bool _fHaveDeferredCursorRedraw; // have we been asked to redraw the cursor while it was being deferred?
bool _fDeferCursorRedraw = false; // whether we should defer redrawing the cursor or not
bool _fHaveDeferredCursorRedraw = false; // have we been asked to redraw the cursor while it was being deferred?
ULONG _ulSize;
ULONG _ulSize = 0;
void _RedrawCursor() noexcept;
void _RedrawCursorAlways() noexcept;
CursorType _cursorType;
CursorType _cursorType = CursorType::Legacy;
};

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{0CF235BD-2DA0-407E-90EE-C467E8BBC714}</ProjectGuid>
<Keyword>Win32Proj</Keyword>

View File

@@ -35,16 +35,10 @@ TextBuffer::TextBuffer(const til::size screenBufferSize,
const UINT cursorSize,
const bool isActiveBuffer,
Microsoft::Console::Render::Renderer& renderer) :
_firstRow{ 0 },
_currentAttributes{ defaultAttributes },
_cursor{ cursorSize, *this },
_storage{},
_unicodeStorage{},
_currentAttributes{ defaultAttributes },
_isActiveBuffer{ isActiveBuffer },
_renderer{ renderer },
_size{},
_currentHyperlinkId{ 1 },
_currentPatternId{ 0 }
_renderer{ &renderer }
{
// initialize ROWs
_storage.reserve(gsl::narrow<size_t>(screenBufferSize.Y));
@@ -56,6 +50,40 @@ TextBuffer::TextBuffer(const til::size screenBufferSize,
_UpdateSize();
}
// Routine Description:
// - Copies the viewport from another text buffer into this one.
// Arguments:
// - OtherBuffer - The text buffer to copy from
// Return Value:
// - <none>
void TextBuffer::CopyViewport(const TextBuffer& other, const Viewport& viewport)
{
const auto top = viewport.Top();
const auto dimensions = viewport.Dimensions();
auto self = this;
if (self->_size.Dimensions() != dimensions)
{
self->~TextBuffer();
try
{
self = new (this) TextBuffer{ dimensions, other.GetCurrentAttributes(), 0, true, *other._renderer };
}
catch (...)
{
self = new (this) TextBuffer{};
throw;
}
}
for (til::CoordType i = 0; i < dimensions.height; ++i)
{
self->GetRowByOffset(i) = other.GetRowByOffset(top + i);
}
self->CopyProperties(other);
}
// Routine Description:
// - Copies properties from another text buffer into this one.
// - This is primarily to copy properties that would otherwise not be specified during CreateInstance
@@ -558,7 +586,7 @@ bool TextBuffer::IncrementCircularBuffer(const bool inVtMode)
// to the logical position 0 in the window (cursor coordinates and all other coordinates).
if (_isActiveBuffer)
{
_renderer.TriggerFlush(true);
_renderer->TriggerFlush(true);
}
// Prune hyperlinks to delete obsolete references
@@ -968,14 +996,14 @@ bool TextBuffer::IsActiveBuffer() const noexcept
Microsoft::Console::Render::Renderer& TextBuffer::GetRenderer() noexcept
{
return _renderer;
return *_renderer;
}
void TextBuffer::TriggerRedraw(const Viewport& viewport)
{
if (_isActiveBuffer)
{
_renderer.TriggerRedraw(viewport);
_renderer->TriggerRedraw(viewport);
}
}
@@ -983,7 +1011,7 @@ void TextBuffer::TriggerRedrawCursor(const til::point position)
{
if (_isActiveBuffer)
{
_renderer.TriggerRedrawCursor(&position);
_renderer->TriggerRedrawCursor(&position);
}
}
@@ -991,7 +1019,7 @@ void TextBuffer::TriggerRedrawAll()
{
if (_isActiveBuffer)
{
_renderer.TriggerRedrawAll();
_renderer->TriggerRedrawAll();
}
}
@@ -999,7 +1027,7 @@ void TextBuffer::TriggerScroll()
{
if (_isActiveBuffer)
{
_renderer.TriggerScroll();
_renderer->TriggerScroll();
}
}
@@ -1007,7 +1035,7 @@ void TextBuffer::TriggerScroll(const til::point delta)
{
if (_isActiveBuffer)
{
_renderer.TriggerScroll(&delta);
_renderer->TriggerScroll(&delta);
}
}
@@ -1015,7 +1043,7 @@ void TextBuffer::TriggerNewTextNotification(const std::wstring_view newText)
{
if (_isActiveBuffer)
{
_renderer.TriggerNewTextNotification(newText);
_renderer->TriggerNewTextNotification(newText);
}
}

View File

@@ -68,6 +68,7 @@ namespace Microsoft::Console::Render
class TextBuffer final
{
public:
TextBuffer() noexcept = default;
TextBuffer(const til::size screenBufferSize,
const TextAttribute defaultAttributes,
const UINT cursorSize,
@@ -76,6 +77,7 @@ public:
TextBuffer(const TextBuffer& a) = delete;
// Used for duplicating properties to another text buffer
void CopyViewport(const TextBuffer& OtherBuffer, const Microsoft::Console::Types::Viewport& viewport);
void CopyProperties(const TextBuffer& OtherBuffer) noexcept;
// row manipulation
@@ -220,19 +222,19 @@ private:
std::vector<ROW> _storage;
Cursor _cursor;
til::CoordType _firstRow; // indexes top row (not necessarily 0)
til::CoordType _firstRow = 0; // indexes top row (not necessarily 0)
TextAttribute _currentAttributes;
// storage location for glyphs that can't fit into the buffer normally
UnicodeStorage _unicodeStorage;
bool _isActiveBuffer;
Microsoft::Console::Render::Renderer& _renderer;
bool _isActiveBuffer = false;
Microsoft::Console::Render::Renderer* _renderer = nullptr;
std::unordered_map<uint16_t, std::wstring> _hyperlinkMap;
std::unordered_map<std::wstring, uint16_t> _hyperlinkCustomIdMap;
uint16_t _currentHyperlinkId;
uint16_t _currentHyperlinkId = 1;
void _RefreshRowIDs(std::optional<til::CoordType> newRowWidth);
@@ -263,7 +265,7 @@ private:
static void _AppendRTFText(std::ostringstream& contentBuilder, const std::wstring_view& text);
std::unordered_map<size_t, std::wstring> _idsAndPatterns;
size_t _currentPatternId;
size_t _currentPatternId = 0;
#ifdef UNIT_TESTING
friend class TextBufferTests;

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{531C23E7-4B76-4C08-8BBD-04164CB628C9}</ProjectGuid>
<Keyword>Win32Proj</Keyword>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
<Import Project="$(OpenConsoleDir)src\wap-common.build.pre.props" />
<PropertyGroup Label="Configuration">
@@ -109,10 +109,6 @@
Since PRI file generation is _before_ manifest generation (for possibly obvious or
important reasons), that doesn't work for us.
-->
<PropertyGroup>
<!-- Only for MSBuild versions < 16.3.0 -->
<_GenerateProjectPriFileDependsOn Condition="$(MSBuildVersion) &lt; '16.3.0'">OpenConsoleLiftDesktopBridgePriFiles;$(_GenerateProjectPriFileDependsOn)</_GenerateProjectPriFileDependsOn>
</PropertyGroup>
<Target Name="OpenConsoleLiftDesktopBridgePriFiles" DependsOnTargets="_ConvertItems">
<ItemGroup>
<_PriFile Include="@(_NonWapProjProjectOutput)" Condition="'%(Extension)' == '.pri'" />

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<!-- License Info -->
<Content Include="$(OpenConsoleDir)src\cascadia\CascadiaPackage\NOTICE.html">

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<ProjectGuid>{416fd703-baa7-4f6e-9361-64f550ec8fca}</ProjectGuid>
<Keyword>Win32Proj</Keyword>

View File

@@ -717,7 +717,7 @@ namespace SettingsModelLocalTests
void DeserializationTests::TestInvalidColorSchemeName()
{
Log::Comment(NoThrowString().Format(
L"Ensure that setting a profile's scheme to a non-existent scheme causes a warning."));
L"Ensure that setting a profile's scheme to a nonexistent scheme causes a warning."));
static constexpr std::string_view settings0String{ R"({
"profiles": [
@@ -751,7 +751,7 @@ namespace SettingsModelLocalTests
void DeserializationTests::ValidateColorSchemeInCommands()
{
Log::Comment(NoThrowString().Format(
L"Ensure that setting a command's color scheme to a non-existent scheme causes a warning."));
L"Ensure that setting a command's color scheme to a nonexistent scheme causes a warning."));
static constexpr std::string_view settings0String{ R"(
{

View File

@@ -253,9 +253,14 @@ namespace SettingsModelLocalTests
{ "command": { "action": "adjustFontSize", "delta": 1 }, "keys": "ctrl+c" },
{ "command": { "action": "adjustFontSize", "delta": 1 }, "keys": "ctrl+d" }
])" };
// GH#13323 - these can be fragile. In the past, the order these get
// re-serialized as has been not entirely stable. We don't really care
// about the order they get re-serialized in, but the tests aren't
// clever enough to compare the structure, only the literal string
// itself. Feel free to change as needed.
static constexpr std::string_view actionsString4B{ R"([
{ "command": { "action": "findMatch", "direction": "next" }, "keys": "ctrl+shift+s" },
{ "command": { "action": "findMatch", "direction": "prev" }, "keys": "ctrl+shift+r" }
{ "command": { "action": "findMatch", "direction": "prev" }, "keys": "ctrl+shift+r" },
{ "command": { "action": "adjustFontSize", "delta": 1 }, "keys": "ctrl+d" }
])" };
// command with name and icon and multiple key chords
@@ -455,7 +460,9 @@ namespace SettingsModelLocalTests
],
"actions": [
{ "command": { "action": "sendInput", "input": "VT Griese Mode" }, "keys": "ctrl+k" }
]
],
"theme": "system",
"themes": []
})" };
const auto settings{ winrt::make_self<implementation::CascadiaSettings>(settingsString) };

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- A note about this project: We're building the test code dll from this
project, but it _MUST_ be run in conjunction with the TestHostApp project.

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- A note about this project: We're building the test code dll from this
project, but it _MUST_ be run in conjunction with the TestHostApp project.

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<ProjectGuid>{A021EDFF-45C8-4DC2-BEF7-36E1B3B8CFE8}</ProjectGuid>
<ProjectName>TestHostApp</ProjectName>

View File

@@ -39,9 +39,6 @@
<ProjectReference Include="$(SolutionDir)src\renderer\dx\lib\dx.vcxproj">
<Project>{48d21369-3d7b-4431-9967-24e81292cf62}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)src\api-ms-win-core-synch-l1-2-0\api-ms-win-core-synch-l1-2-0.vcxproj">
<Project>{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}</Project>
</ProjectReference>
</ItemGroup>
<ItemDefinitionGroup>
<ClCompile>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<ProjectGuid>{43ce4ce5-0010-4b99-9569-672670d26e26}</ProjectGuid>
<Keyword>Win32Proj</Keyword>

View File

@@ -103,6 +103,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
auto proposedCommandline = false;
Remoting::ProposeCommandlineResult result{ nullptr };
auto attempts = 0;
while (!proposedCommandline)
{
try
@@ -118,78 +119,78 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
proposedCommandline = true;
}
catch (const winrt::hresult_error& e)
catch (...)
{
// We did not successfully ask the king what to do. They
// hopefully just died here. That's okay, let's just go ask the
// next in the line of succession. At the very worst, we'll find
// _us_, (likely last in the line).
// We did not successfully ask the king what to do. This could
// be for many reasons. Most commonly, the monarch died as we
// were talking to it. That could be a RPC_SERVER_UNAVAILABLE_HR
// or RPC_CALL_FAILED_HR (GH#12666). We also saw a
// RPC_S_CALL_FAILED_DNE in GH#11790. Ultimately, if this is
// gonna fail, we want to just try again, regardless of the
// cause. That's why we're no longer checking what the exception
// was, we're just always gonna try again regardless.
//
// If the king returned some _other_ error here, than lets
// bubble that up because that's a real issue.
//
// I'm checking both these here. I had previously got a
// RPC_S_CALL_FAILED about here once.
if (e.code() == RPC_SERVER_UNAVAILABLE_HR || e.code() == RPC_CALL_FAILED_HR)
// They hopefully just died here. That's okay, let's just go
// ask the next in the line of succession. At the very worst,
// we'll find _us_, (likely last in the line).
TraceLoggingWrite(g_hRemotingProvider,
"WindowManager_proposeToMonarch_unexpectedExceptionFromKing",
TraceLoggingInt32(attempts, "attempts", "How many times we've tried"),
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
LOG_CAUGHT_EXCEPTION();
attempts++;
if (attempts >= 10)
{
// We've tried 10 times to find the monarch, failing each
// time. Since we have no idea why, we're guessing that in
// this case, there's just a Monarch registered that's
// misbehaving. In this case, just fall back to
// "IsolatedMonarchMode" - we can't trust the currently
// registered one.
TraceLoggingWrite(g_hRemotingProvider,
"WindowManager_proposeToMonarch_kingDied",
"WindowManager_TooManyAttempts_NullMonarchIsolateMode",
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
_monarch = winrt::make<winrt::Microsoft::Terminal::Remoting::implementation::Monarch>();
_createCallbacks();
}
else
{
// We failed to ask the monarch. It must have died. Try and
// find the real monarch. Don't perform an election, that
// assumes we have a peasant, which we don't yet.
_createMonarchAndCallbacks();
// _createMonarchAndCallbacks will initialize _isKing
if (_isKing)
{
// We became the king. We don't need to ProposeCommandline to ourself, we're just
// going to do it.
//
// Return early, because there's nothing else for us to do here.
TraceLoggingWrite(g_hRemotingProvider,
"WindowManager_proposeToMonarch_becameKing",
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
// In WindowManager::ProposeCommandline, had we been the
// king originally, we would have started by setting
// this to true. We became the monarch here, so set it
// here as well.
_shouldCreateWindow = true;
return;
}
// Here, we created the new monarch, it wasn't us, so we're
// gonna go through the while loop again and ask the new
// king.
TraceLoggingWrite(g_hRemotingProvider,
"WindowManager_proposeToMonarch_tryAgain",
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
}
else
if (_isKing)
{
// We became the king. We don't need to ProposeCommandline to ourself, we're just
// going to do it.
//
// Return early, because there's nothing else for us to do here.
TraceLoggingWrite(g_hRemotingProvider,
"WindowManager_proposeToMonarch_unexpectedResultFromKing",
"WindowManager_proposeToMonarch_becameKing",
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
LOG_CAUGHT_EXCEPTION();
throw;
// In WindowManager::ProposeCommandline, had we been the
// king originally, we would have started by setting
// this to true. We became the monarch here, so set it
// here as well.
_shouldCreateWindow = true;
return;
}
}
catch (...)
{
// If the monarch (maybe us) failed for _any other reason_ than
// them dying. This IS quite unexpected. Let this bubble out.
// Here, we created the new monarch, it wasn't us, so we're
// gonna go through the while loop again and ask the new
// king.
TraceLoggingWrite(g_hRemotingProvider,
"WindowManager_proposeToMonarch_unexpectedExceptionFromKing",
"WindowManager_proposeToMonarch_tryAgain",
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
LOG_CAUGHT_EXCEPTION();
throw;
}
}
@@ -345,15 +346,10 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
CLSCTX_LOCAL_SERVER);
}
// NOTE: This can throw! Callers include:
// - the constructor, who performs this in a loop until it successfully
// find a a monarch
// - the performElection method, which is called in the waitOnMonarch
// thread. All the calls in that thread are wrapped in try/catch's
// already.
// - _createOurPeasant, who might do this in a loop to establish us with the
// monarch.
void WindowManager::_createMonarchAndCallbacks()
// Tries to instantiate a monarch, tries again, and eventually either throws
// (so that the caller will try again) or falls back to the isolated
// monarch.
void WindowManager::_redundantCreateMonarch()
{
_createMonarch();
@@ -399,9 +395,26 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
winrt::hresult_error(E_UNEXPECTED, L"Did not expect the Monarch to ever be null");
}
}
}
// NOTE: This can throw! Callers include:
// - the constructor, who performs this in a loop until it successfully
// find a a monarch
// - the performElection method, which is called in the waitOnMonarch
// thread. All the calls in that thread are wrapped in try/catch's
// already.
// - _createOurPeasant, who might do this in a loop to establish us with the
// monarch.
void WindowManager::_createMonarchAndCallbacks()
{
_redundantCreateMonarch();
// We're pretty confident that we have a Monarch here.
_createCallbacks();
}
// Check if we became the king, and if we are, wire up callbacks.
void WindowManager::_createCallbacks()
{
// Save the result of checking if we're the king. We want to avoid
// unnecessary calls back and forth if we can.
_isKing = _areWeTheKing();

View File

@@ -72,7 +72,9 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
void _registerAsMonarch();
void _createMonarch();
void _redundantCreateMonarch();
void _createMonarchAndCallbacks();
void _createCallbacks();
bool _areWeTheKing();
winrt::Microsoft::Terminal::Remoting::IPeasant _createOurPeasant(std::optional<uint64_t> givenID,
const winrt::hstring& givenName);

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<ProjectGuid>{27b5aaeb-a548-44cf-9777-f8baa32af7ae}</ProjectGuid>
<ProjectName>Microsoft.Terminal.Remoting</ProjectName>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<ProjectGuid>{f2ed628a-db22-446f-a081-4cc845b51a2b}</ProjectGuid>
<ProjectName>WindowsTerminalShellExt</ProjectName>

View File

@@ -606,7 +606,7 @@ namespace winrt::TerminalApp::implementation
{
if (const auto activeTab{ _GetFocusedTabImpl() })
{
activeTab->ActivateColorPicker();
activeTab->RequestColorPicker();
}
args.Handled(true);
}

View File

@@ -782,32 +782,31 @@ namespace winrt::TerminalApp::implementation
try
{
auto newSettings = _isUwp ? CascadiaSettings::LoadUniversal() : CascadiaSettings::LoadAll();
_settings = newSettings;
if (_settings.GetLoadingError())
if (newSettings.GetLoadingError())
{
_settingsLoadExceptionText = _GetErrorText(_settings.GetLoadingError().Value());
_settingsLoadExceptionText = _GetErrorText(newSettings.GetLoadingError().Value());
return E_INVALIDARG;
}
else if (!_settings.GetSerializationErrorMessage().empty())
else if (!newSettings.GetSerializationErrorMessage().empty())
{
_settingsLoadExceptionText = _settings.GetSerializationErrorMessage();
_settingsLoadExceptionText = newSettings.GetSerializationErrorMessage();
return E_INVALIDARG;
}
_warnings.clear();
for (uint32_t i = 0; i < _settings.Warnings().Size(); i++)
for (uint32_t i = 0; i < newSettings.Warnings().Size(); i++)
{
_warnings.push_back(_settings.Warnings().GetAt(i));
_warnings.push_back(newSettings.Warnings().GetAt(i));
}
_hasSettingsStartupActions = false;
const auto startupActions = _settings.GlobalSettings().StartupActions();
const auto startupActions = newSettings.GlobalSettings().StartupActions();
if (!startupActions.empty())
{
_settingsAppArgs.FullResetState();
ExecuteCommandlineArgs args{ _settings.GlobalSettings().StartupActions() };
ExecuteCommandlineArgs args{ newSettings.GlobalSettings().StartupActions() };
auto result = _settingsAppArgs.ParseArgs(args);
if (result == 0)
{
@@ -822,6 +821,7 @@ namespace winrt::TerminalApp::implementation
}
}
_settings = std::move(newSettings);
hr = _warnings.empty() ? S_OK : S_FALSE;
}
catch (const winrt::hresult_error& e)
@@ -1500,6 +1500,17 @@ namespace winrt::TerminalApp::implementation
return _root ? _root->AlwaysOnTop() : false;
}
bool AppLogic::AutoHideWindow()
{
if (!_loadedInitialSettings)
{
// Load settings if we haven't already
LoadSettings();
}
return _settings.GlobalSettings().AutoHideWindow();
}
Windows::Foundation::Collections::IMapView<Microsoft::Terminal::Control::KeyChord, Microsoft::Terminal::Settings::Model::Command> AppLogic::GlobalHotkeys()
{
return _settings.GlobalSettings().ActionMap().GlobalHotkeys();

View File

@@ -79,6 +79,7 @@ namespace winrt::TerminalApp::implementation
bool Fullscreen() const;
void Maximized(bool newMaximized);
bool AlwaysOnTop() const;
bool AutoHideWindow();
bool ShouldUsePersistedLayout();
bool ShouldImmediatelyHandoffToElevated();

View File

@@ -70,6 +70,7 @@ namespace TerminalApp
Boolean Fullscreen { get; };
void Maximized(Boolean newMaximized);
Boolean AlwaysOnTop { get; };
Boolean AutoHideWindow { get; };
void IdentifyWindow();
String WindowName;

View File

@@ -525,9 +525,9 @@ namespace winrt::TerminalApp::implementation
}
// Method Description:
// This event is called when the user clicks on an ChevronLeft button right
// This event is called when the user clicks on a ChevronLeft button right
// next to the ParentCommandName (e.g. New Tab...) above the subcommands list.
// It'll go up a level when the users click the button.
// It'll go up a single level when the user clicks the button.
// Arguments:
// - sender: the button that got clicked
// Return Value:
@@ -536,12 +536,32 @@ namespace winrt::TerminalApp::implementation
const Windows::UI::Xaml::RoutedEventArgs&)
{
_PreviewActionHandlers(*this, nullptr);
_nestedActionStack.Clear();
ParentCommandName(L"");
_currentNestedCommands.Clear();
_searchBox().Focus(FocusState::Programmatic);
const auto previousAction{ _nestedActionStack.GetAt(_nestedActionStack.Size() - 1) };
_nestedActionStack.RemoveAtEnd();
// Repopulate nested commands when the root has not been reached yet
if (_nestedActionStack.Size() > 0)
{
const auto newPreviousAction{ _nestedActionStack.GetAt(_nestedActionStack.Size() - 1) };
const auto actionPaletteItem{ newPreviousAction.Item().try_as<winrt::TerminalApp::ActionPaletteItem>() };
ParentCommandName(actionPaletteItem.Command().Name());
_updateCurrentNestedCommands(actionPaletteItem.Command());
}
else
{
ParentCommandName(L"");
_currentNestedCommands.Clear();
}
_updateFilteredActions();
_filteredActionsView().SelectedIndex(0);
const auto lastSelectedIt = std::find_if(begin(_filteredActions), end(_filteredActions), [&](const auto& filteredCommand) {
return filteredCommand.Item().Name() == previousAction.Item().Name();
});
const auto lastSelectedIndex = static_cast<int32_t>(std::distance(begin(_filteredActions), lastSelectedIt));
_scrollToIndex(lastSelectedIt != end(_filteredActions) ? lastSelectedIndex : 0);
}
// Method Description:
@@ -639,14 +659,7 @@ namespace winrt::TerminalApp::implementation
// to pick from.
_nestedActionStack.Append(filteredCommand);
ParentCommandName(actionPaletteItem.Command().Name());
_currentNestedCommands.Clear();
for (const auto& nameAndCommand : actionPaletteItem.Command().NestedCommands())
{
const auto action = nameAndCommand.Value();
auto nestedActionPaletteItem{ winrt::make<winrt::TerminalApp::implementation::ActionPaletteItem>(action) };
auto nestedFilteredCommand{ winrt::make<FilteredCommand>(nestedActionPaletteItem) };
_currentNestedCommands.Append(nestedFilteredCommand);
}
_updateCurrentNestedCommands(actionPaletteItem.Command());
_updateUIForStackChange();
}
@@ -1108,6 +1121,25 @@ namespace winrt::TerminalApp::implementation
}
}
// Method Description:
// - Update the list of current nested commands to match that of the
// given parent command.
// Arguments:
// - parentCommand: the command with an optional list of nested commands.
// Return Value:
// - <none>
void CommandPalette::_updateCurrentNestedCommands(const winrt::Microsoft::Terminal::Settings::Model::Command& parentCommand)
{
_currentNestedCommands.Clear();
for (const auto& nameAndCommand : parentCommand.NestedCommands())
{
const auto action = nameAndCommand.Value();
auto nestedActionPaletteItem{ winrt::make<winrt::TerminalApp::implementation::ActionPaletteItem>(action) };
auto nestedFilteredCommand{ winrt::make<FilteredCommand>(nestedActionPaletteItem) };
_currentNestedCommands.Append(nestedFilteredCommand);
}
}
// Method Description:
// - Dismiss the command palette. This will:
// * select all the current text in the input box

View File

@@ -96,6 +96,8 @@ namespace winrt::TerminalApp::implementation
void _updateFilteredActions();
void _updateCurrentNestedCommands(const winrt::Microsoft::Terminal::Settings::Model::Command& parentCommand);
std::vector<winrt::TerminalApp::FilteredCommand> _collectFilteredActions();
void _close();

View File

@@ -89,12 +89,8 @@ winrt::fire_and_forget Jumplist::UpdateJumplist(const CascadiaSettings& settings
winrt::com_ptr<IObjectCollection> jumplistItems;
jumplistItems.capture(jumplistInstance, &ICustomDestinationList::BeginList, &slots);
// It's easier to clear the list and re-add everything. The settings aren't
// updated often, and there likely isn't a huge amount of items to add.
THROW_IF_FAILED(jumplistItems->Clear());
// Update the list of profiles.
THROW_IF_FAILED(_updateProfiles(jumplistItems.get(), strongSettings.ActiveProfiles().GetView()));
_updateProfiles(jumplistItems.get(), strongSettings.ActiveProfiles().GetView());
// TODO GH#1571: Add items from the future customizable new tab dropdown as well.
// This could either replace the default profiles, or be added alongside them.
@@ -116,26 +112,22 @@ winrt::fire_and_forget Jumplist::UpdateJumplist(const CascadiaSettings& settings
// - profiles - The profiles to add to the jumplist
// Return Value:
// - S_OK or HRESULT failure code.
[[nodiscard]] HRESULT Jumplist::_updateProfiles(IObjectCollection* jumplistItems, winrt::Windows::Foundation::Collections::IVectorView<Profile> profiles) noexcept
void Jumplist::_updateProfiles(IObjectCollection* jumplistItems, winrt::Windows::Foundation::Collections::IVectorView<Profile> profiles)
{
try
// It's easier to clear the list and re-add everything. The settings aren't
// updated often, and there likely isn't a huge amount of items to add.
THROW_IF_FAILED(jumplistItems->Clear());
for (const auto& profile : profiles)
{
for (const auto& profile : profiles)
{
// Craft the arguments following "wt.exe"
auto args = fmt::format(L"-p {}", to_hstring(profile.Guid()));
// Craft the arguments following "wt.exe"
auto args = fmt::format(L"-p {}", to_hstring(profile.Guid()));
// Create the shell link object for the profile
winrt::com_ptr<IShellLinkW> shLink;
const auto normalizedIconPath{ _normalizeIconPath(profile.Icon()) };
RETURN_IF_FAILED(_createShellLink(profile.Name(), normalizedIconPath, args, shLink.put()));
RETURN_IF_FAILED(jumplistItems->AddObject(shLink.get()));
}
return S_OK;
// Create the shell link object for the profile
const auto normalizedIconPath{ _normalizeIconPath(profile.Icon()) };
const auto shLink = _createShellLink(profile.Name(), normalizedIconPath, args);
THROW_IF_FAILED(jumplistItems->AddObject(shLink.get()));
}
CATCH_RETURN();
}
// Method Description:
@@ -150,36 +142,27 @@ winrt::fire_and_forget Jumplist::UpdateJumplist(const CascadiaSettings& settings
// - shLink: The shell link object to return.
// Return Value:
// - S_OK or HRESULT failure code.
[[nodiscard]] HRESULT Jumplist::_createShellLink(const std::wstring_view name,
const std::wstring_view path,
const std::wstring_view args,
IShellLinkW** shLink) noexcept
winrt::com_ptr<IShellLinkW> Jumplist::_createShellLink(const std::wstring_view name, const std::wstring_view path, const std::wstring_view args)
{
try
{
auto sh = winrt::create_instance<IShellLinkW>(CLSID_ShellLink, CLSCTX_ALL);
auto sh = winrt::create_instance<IShellLinkW>(CLSID_ShellLink, CLSCTX_ALL);
const auto module{ GetWtExePath() };
RETURN_IF_FAILED(sh->SetPath(module.data()));
RETURN_IF_FAILED(sh->SetArguments(args.data()));
const auto module{ GetWtExePath() };
THROW_IF_FAILED(sh->SetPath(module.data()));
THROW_IF_FAILED(sh->SetArguments(args.data()));
PROPVARIANT titleProp;
titleProp.vt = VT_LPWSTR;
titleProp.pwszVal = const_cast<wchar_t*>(name.data());
PROPVARIANT titleProp;
titleProp.vt = VT_LPWSTR;
titleProp.pwszVal = const_cast<wchar_t*>(name.data());
PROPVARIANT iconProp;
iconProp.vt = VT_LPWSTR;
iconProp.pwszVal = const_cast<wchar_t*>(path.data());
PROPVARIANT iconProp;
iconProp.vt = VT_LPWSTR;
iconProp.pwszVal = const_cast<wchar_t*>(path.data());
auto propStore{ sh.as<IPropertyStore>() };
RETURN_IF_FAILED(propStore->SetValue(PKEY_Title, titleProp));
RETURN_IF_FAILED(propStore->SetValue(PKEY_AppUserModel_DestListLogoUri, iconProp));
auto propStore{ sh.as<IPropertyStore>() };
THROW_IF_FAILED(propStore->SetValue(PKEY_Title, titleProp));
THROW_IF_FAILED(propStore->SetValue(PKEY_AppUserModel_DestListLogoUri, iconProp));
RETURN_IF_FAILED(propStore->Commit());
THROW_IF_FAILED(propStore->Commit());
*shLink = sh.detach();
return S_OK;
}
CATCH_RETURN();
return sh;
}

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