Compare commits

..

45 Commits

Author SHA1 Message Date
Dustin L. Howett
44b2d4d2a8 Migrate spelling-0.0.21 changes from main 2020-06-29 17:56:32 -07:00
Dustin L. Howett
f6019dcd96 Migrate spelling-0.0.19 changes from main 2020-06-29 17:56:32 -07:00
Dustin L. Howett
de2ccfbc13 Update Cascadia Code to 2007.01 (#6721) 2020-06-29 17:56:51 -07:00
Dustin L. Howett
b981537ca5 Hardcode the paths to Windows PowerShell and CMD (#6684)
Occasionally, we get users with corrupt PATH environment variables: they
can't lauch PowerShell, because for some reason it's dropped off their
PATH. We also get users who have stray applications named
`powershell.exe` just lying around in random system directories.

We can combat both of these issues by simply hardcoding where we expect
PowerShell and CMD to live. %SystemRoot% was chosen over %WINDIR%
because apparently (according to Stack Overflow), SystemPath is
read-only and WINDIR isn't.

Refs #6039, #4390, #4228 (powershell was not found)
Refs #4682, Fixes #6082 (stray powershell.exe)

(cherry picked from commit 2fc1ef04ce)
2020-06-26 12:10:24 -07:00
Michael Niksa
3cfbd7a46c Improve perf by avoiding vector reallocation in renderer clusters and VT output graphics options (#6420)
## Summary of the Pull Request
Caches vectors in the class and uses a new helper to opportunistically shrink/grow as viewport sizes change in order to save performance on alloc/free of commonly used vectors.

## PR Checklist
* [x] Scratches a perf itch.
* [x] I work here.
* [x] wil tests added
* [x] No add'l doc.
* [x] Am core contributor.

## Detailed Description of the Pull Request / Additional comments
Two fixes:
1. For outputting lots of text, the base renderer class spent a lot of time allocating and freeing and reallocating the `Cluster` vector that adapts the text buffer information into render clusters. I've now cached this vector in the base render class itself and I shrink/grow it based on the viewport update that happens at the top of every frame. To prevent too much thrashing in the downward/shrink direction, I wrote the `til::manage_vector` helper that contains a threshold to only shrink if it asks for small enough of a size relative to the existing one. I used 80% of the existing size as the threshold for this one.
2. For outputting lots of changing colors, the VT graphics output engine spent a bunch of time allocating and reallocating the vector for `GraphicsOptions`. This one doesn't really have a predictable size, but I never expect it to get extremely big. So I just held it in the base class.

## Validation Steps Performed
* [x] Ran the til unit test
* [x] Checked render cluster vector time before/after against `big.txt` from #1064
* [x] Checked VT graphics output vector time before/after against `cacafire`

Case | Before | After
---|---|---|
`big.txt` | ![image](https://user-images.githubusercontent.com/18221333/84088632-cbaa8400-a9a1-11ea-8932-04b2e12a0477.png) | ![image](https://user-images.githubusercontent.com/18221333/84088996-b6822500-a9a2-11ea-837c-5e32a110156e.png)
`cacafire` | ![image](https://user-images.githubusercontent.com/18221333/84089153-22648d80-a9a3-11ea-8567-c3d80efa16a6.png) | ![image](https://user-images.githubusercontent.com/18221333/84089190-34463080-a9a3-11ea-98e5-a236b12330d6.png)

(cherry picked from commit 0c93b2ebbe)
2020-06-24 15:53:55 -07:00
greg904
a5518a0bb9 Throttle scrollbar updates in TermControl to ~one per 8ms (#4608)
In addition to the below (original) description, this commit introduces
a ThrottledFunc template that can throttle _any_ function. It applies
that type to muffle updates to the scrollbar.

---

Redo #3531 but without the bug that it caused (#3622) which is why it
was reverted.

I'm sorry if I explain this badly. If you don't understand a part, make
sure to let me know and I will explain it better.

### Explanation

How it worked before: `Terminal` signals that viewport changed ->
`TermControl::_TerminalScrollPositionChanged` gets called on the
terminal thread -> it dispatches work for later to be ran the UI thread
to updates the scrollbar's values

Why it's bad:
* If we have many viewport changes, it will create a long stack of
  operations to run. Instead, we should just update the scroll bar with
  the most recent information that we know.
* Imagine if the rate that the work gets pushed on the UI thread is
  greater than the rate that it can handle: it might freeze?
* No need to be real time, we can wait just a little bit (8ms) to
  accumulate viewport changes before we actually change the scroll bar's
  value because it appears to be expensive (see perf below).

Now: `Terminal` signals that viewport changed ->
`TermControl::_TerminalScrollPositionChanged` gets called on the
terminal thread -> it tells the `ScrollBarUpdater` about a new update ->
the `ScrollBarUpdater` only runs one job (I don't know if that's the
right term) on the UI thread at a time. If a job is already running but
hasn't updated the scroll bar yet, it changes the setting in the already
existing job to update the scroll bar with the new values. A job "waits"
some time before doing the update to throttle updates because we don't
need real time scroll bar updates. -> eventually, it updates the scroll
bar If the user scrolls when a scroll bar update is pending, we keep the
scroll bar's Maximum and Minimum but let the user choose its new Value
with the `CancelPendingValueChange` method.

### Note

Also I changed a little bit the code from the Terminal to notify the
TermControl less often when possible.

I tried to scroll with the scroll bar, with the mouse wheel. I tried to
scroll while content is being outputted.

I tried to reproduce the crash from #2248 without success (good).

Co-authored-by: Leonard Hecker <leonard@hecker.io>

Closes #3622

(cherry picked from commit 25df527743)

# Conflicts:
#	.github/actions/spell-check/dictionary/apis.txt
2020-06-24 15:53:55 -07:00
James Holderness
9637c090c0 Correct the default 6x6x6 palette entries (#5999)
There is a range of 216 colors in the default 256-color table that is
meant to be initialized with a 6x6x6 color cube, with each color
component iterating over the values `00`, `5F`, `87`, `AF`, `D7`, and
`FF`. A few of the entries incorrectly had the _red_ component has `DF`,
when it should have been `D7`.  This PR corrects those entries. It also
removes a bit of unnecessary whitespace in the first 100 entries.

## Validation Steps Performed

I have a visual test script that renders the full 256-color palette,
using both the indexed color sequence (`SGR 38;5`) and the equivalent
rgb representation (`SGR 38;2`) side by side. Although the difference
was subtle when it was incorrect, I can now see that it has been fixed.

Closes #5994

(cherry picked from commit 5d6fdf3897)
2020-06-24 15:53:55 -07:00
Mike Griese
a1bb78f2a7 Implement drag-drop paste for text (#5865)
## Summary of the Pull Request

Implements drag-dropping text onto a `TermControl`, in addition to the already supported drag-drop of files.

## References
* [StandardDataFormats](https://docs.microsoft.com/en-us/uwp/api/windows.applicationmodel.datatransfer.standarddataformats?view=winrt-18362)
* [StandardDataFormats::Text](https://docs.microsoft.com/en-us/uwp/api/windows.applicationmodel.datatransfer.standarddataformats.text?view=winrt-18362#Windows_ApplicationModel_DataTransfer_StandardDataFormats_Text)
* [GetTextAsync](https://docs.microsoft.com/en-us/uwp/api/windows.applicationmodel.datatransfer.datapackageview.gettextasync?view=winrt-18362)

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

## Detailed Description of the Pull Request / Additional comments

Oh I also changed "Copy path to file" to "Paste path to file". I thought that actually made more sense here

## Validation Steps Performed
* Tested manually that text and files still work.

(cherry picked from commit 88ed94d2ac)
2020-06-24 15:53:55 -07:00
Mike Griese
a9adc93776 Manually close tabs when they're closed while dragging them (#5883)
## Summary of the Pull Request

When we're dragging the tab around, if you execute a `ClosePane`/`CloseTab`, then we should make sure to actually activate a new tab, so that focus doesn't just fall into the void.

## References

* This is almost exactly #5799, but with rearranging tabs

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

## Detailed Description of the Pull Request / Additional comments
We suppress `_OnTabItemsChanged` events during a rearrange, so if a tab is closed while we're rearranging tabs, the we don't fire the `SelectionChanged` event that we usually do during a close that would select the new tab.

## Validation Steps Performed
* Tested manually
  - Confirmed that tragging a tab out, closing it, then dragging it back in does nothing.

(cherry picked from commit 1422714af6)
2020-06-24 15:53:55 -07:00
greg904
a4d6ad2c43 Open the system menu when user right clicks the drag bar (#6443)
Related to #1375 ("Click/Right click icon should display
Minimize/Maximize/Close menu")

(cherry picked from commit 30a6c1e10a)
2020-06-24 15:36:58 -07:00
greg904
6a4e0b952b Clear cached runs after translate_y (#6501)
"While re-reading the code, I found out that I forgot to do clear cached runs
after translate_y in c360b7588ff8d389b49a4ed60cdee51401a5e172."

(cherry picked from commit c0ffc9b6dc)
2020-06-24 15:36:22 -07:00
greg904
f46d1fbad5 Add fast path to til::bitmap::translate using bitshifts (#6493)
This commit adds a fast path to `til::bitmap::translate`: use bit shifts
when the delta is vertical.

Performance while printing the content of a big file, with the patch
from #6492 which hasn't been merged yet, in Release mode:

Before:
* translate represents 13.08% of samples in InvalidateScroll

After:
* translate represents  0.32% of samples in InvalidateScroll

## Validation

Tests passed.

(cherry picked from commit c360b7588f)
2020-06-24 15:36:22 -07:00
Mike Griese
c53acfa901 Draw the cursor underneath text, and above the background (#6337)
## Summary of the Pull Request

![textAboveCursor003](https://user-images.githubusercontent.com/18356694/83681722-67a24d00-a5a8-11ea-8d9b-2d294065e4e4.gif)

This is the plan that @miniksa suggested to me. Instead of trying to do lots of work in all the renderers to do backgrounds as one pass, and foregrounds as another, we can localize this change to basically just the DX renderer.
1. First, we give the DX engine a "heads up" on where the cursor is going to be drawn during the frame, in `PrepareRenderInfo`.
  - This function is left unimplemented in the other render engines.
2. While printing runs of text, the DX renderer will try to paint the cursor in `CustomTextRenderer::DrawGlyphRun` INSTEAD of `DxEngine::PaintCursor`. This lets us weave the cursor background between the text background and the text.

## References

* #6151 was a spec in this general area. I should probably go back and update it, and we should probably approve that first.
* #6193 is also right up in this mess

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

## Detailed Description of the Pull Request / Additional comments

* This is essentially `"cursorTextColor": "textForeground"` from #6151.
* A follow up work item is needed to add support for the current behavior, (`"cursorTextColor": null`), and hooking up that setting to the renderer.

(cherry picked from commit 1fcd95704d)
2020-06-24 15:29:17 -07:00
Mike Griese
6c25248d7b Get rid of the padding above the tab row when maximized (#5881)
## Summary of the Pull Request

When we maximize the window, shrink the caption buttons (the min, max, close buttons) down to 32px tall, to be the same height as the `TabRowControl`. This way, the tabs will be flush with the top of the display.

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

## Detailed Description of the Pull Request / Additional comments

I tried for a couple hours this morning to do this as a `VisualState`. First I tried doing it as one on the TabRow, which I had very little success with. Then, I eventually realized that the TabRow wasn't even responsible for the padding there, it was being created by the fact that the caption buttons were too tall. Again, I tried to use the existing `VisualState`s they have defined for this, but I couldn't figure out how to do that.

I think the visual state solution would be _cleaner_, so if someone knows how to do that instead, please let me know.

## Validation Steps Performed

* Maximized/restored the Terminal on my display with the taskbar on the bottom
* Maximized/restored the Terminal on my display with the taskbar on the top

(cherry picked from commit c373ebcd8d)
2020-06-24 15:29:17 -07:00
Mike Griese
b592d5beb7 Make sure to update the maximize button's visual state on launch (#5988)
## Summary of the Pull Request
This is an enormously trivial nit - when we launch maximized, we don't draw the maximize button in the "restore" state.

This PR changes the terminal to manually update the Maximize button on launch, once the titlebar is added to the UI tree.

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

(cherry picked from commit 2af722b43d)
2020-06-24 15:29:17 -07:00
Michael Niksa
c6fc68e345 Update wil. Fixes GDI handle leak (#6229)
## Summary of the Pull Request
When resizing the window title, a GDI object would be leaked. This has to do with our island message handler using `wil` to track these objects and `wil` having a bug.

## References
microsoft/wil#100

## PR Checklist
* [x] Closes #5949
* [x] I work here.
* [x] Tested manually
* [x] Doc not required.
* [x] Am core contributor.

## Validation Steps Performed
* [x] Added the GDI Objects column to Task Manager, set the Terminal to use the `titleWidth` size tabs, then changed the title a bunch with PowerShell. Confirmed repro before (increasing GDI count). Confirmed it's gone after (no change to object count).

(cherry picked from commit 48b3262eaa)
2020-06-24 15:29:17 -07:00
Alex Hicks
ece96f5811 Fix #6079, allow pasting from Explorer's 'Copy Address' (#6146)
Fixes #6079 by implementing support for IStorageItem clipboard contents. Manually tested, seems to work for both types of address-copying from Explorer (as well as normal text).

## PR Checklist
* [x] Closes #6079
* Not sure what tests would be useful here, it's mostly to do with what Explorer's doing

Not enormously familiar with C++ or this codebase, so happy to make changes as requested.

## Validation Steps Performed

Ran the terminal, pasted from several different sources (explorer's various copy functions + plaintext)

(cherry picked from commit f1b67b3683)
2020-06-24 15:29:17 -07:00
Dustin L. Howett
fdb2fe5f92 Move all wildcards into targets or expand them (#6406)
Wildcards are not allowed in toplevel ItemGroups in vcxproj; they must
be generated by targets.

We mostly use wildcards for pulling in PRI files that are dumped on disk
by the translation tool. We don't want to check those in, so we can't
expand references to them.

To that end, I've introduced a new target that will take a list of
folders containing resw files and expand wildcards under them.

All[1] other wildcards have been moved into their respective targets
_or_ simply expanded.

[1]: Nothing has complained about the resource wildcards in
CascadiaResources.build.items, so I haven't exploded it yet.

Fixes #6214.

(cherry picked from commit e3ee5838a7)
2020-06-24 15:29:17 -07:00
Anurag Thakur
c5df73ef4c Animate Hover state change of CaptionButtons (#6303)
<!-- 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
As discussed in #6293 , this PR adds a fade animation to button background when pointer hover ends
<!-- 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 #6293
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Requires documentation to be 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

<!-- 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
Added storyboarded coloranimations to the visualstategroup of captionbuttons
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Tested manually

(cherry picked from commit a34f1e2ad4)
2020-06-24 15:29:17 -07:00
Dustin L. Howett
6ff8ba7728 Reintroduce the check for VT_INPUT_MODE in AdaptDispatch (#6485)
This commit reverts the removal of the "SSH hack" in #5383. It was
originally added as a solution to #4911, when we realized that SSH would
request the SS3 cursor key encoding but we weren't equipped to handle
it.

A number of folks have filed issues that, in summary, say "when I use
SSH, I can't select/copy/paste text". It turns out that SSH will _also_
pass through requests for mouse input. Terminal dutifully responds to
those requests, of course, by disabling mouse selection/copy/paste. SSH
is **NOT** actually in VT_INPUT_MODE, so it will never receive the mouse
messages.

It's important to note that even with #376 fixed, we are still required
to keep this check. With the closure of #376, we'll be able to convert
VT mouse input back into Win32 mouse input for Win32 applications . . .
but SSH also doesn't know how to handle Win32 mouse input.

Fixes #6476.
Fixes #6196.
Fixes #5704.
Fixes #5608.

(cherry picked from commit 5e2c4c66e3)
2020-06-24 15:29:16 -07:00
Dustin L. Howett (MSFT)
0dfe1bed1e Partially regenerate codepoint widths from Emoji 13.0 (#5934)
This removes all glyphs from the emoji list that do not default to
"emoji presentation" (EPres). It removes all local overrides, but retains
the comments about the emoji we left out that are Microsoft-specific.

This brings us fully in line with the most popular Terminals on OS X,
except that we squash our emoji down to fit in one cell and they let
them hang over the edges and damage other characters. Oh well.

## Detailed Description of the Pull Request / Additional comments

Late Friday evening, I tested my emoji test file on iTerm2. In so doing, I realized
that @j4james and @leonMSFT were right the entire time in #5914: Emoji
that require `U+FE0F` must not be double-width by default.

I finally banged up a powershell script that parses the UCD and emits a codepoint
width table. Once checked in, this will be definitive.

Refs #900, #5914.
Fixes #5941.

(cherry picked from commit ba1a298d6b)
2020-05-17 13:33:55 -07:00
Dustin L. Howett (MSFT)
bae91cee67 version: bump to 1.0 (!) 2020-05-15 22:08:15 -07:00
Dustin L. Howett (MSFT)
d7a54cb07d Update Cascadia Code to 2005.15 (#5930)
(cherry picked from commit 71e29b1617)
2020-05-15 13:47:20 -07:00
Dustin L. Howett (MSFT)
09f02dffe2 CodepointWidthDetector: reclassify U+25FB, U+25FC as Narrow (#5914)
This seems to be in line with the emoji-sequences table in the latest
version of the Unicode standard: those glyphs require U+FE0F to activate
their emoji presentation. Since we don't support composing U+FE0F, we
should not present them as emoji by default.

Fixes #5910.

Yes, I hate this.

(cherry picked from commit c39f9c6626)
2020-05-14 16:56:08 -07:00
Mike Griese
70cb335fd1 Fix an accidental regression from #5771 (#5870)
This PR reverts a relatively minor change that was made incorrectly to
ConPTY in #5771.

In that PR, I authored two tests. One of them actually caught the bug
that was supposed to be fixed by #5771. The other test was simply
authored during the investigation. I believed at the time that the test
revealed a bug in conpty that was fixed by _removing_ this block of
code. However, an investigation itno #5839 revealed that this code was
actually fairly critical.

So, I'm also _skipping_ this buggy test for now. I'm also adding a
specific test case to this bug.

The problem in the bugged case of `WrapNewLineAtBottom` is that
`WriteCharsLegacy` is wrapping the bottom row of the ConPTY buffer,
which is causing the cursor to automatically move to the next line in
the buffer. This is because `WriteCharsLegacy` isn't being called with
the `WC_DELAY_EOL_WRAP` flag. So, in that test case,
* The client emits a wrapped line to conpty
* conpty fills the bottom line with that text, then dutifully increments
  the buffer to make space for the cursor on a _new_ bottom line.
* Conpty reprints the last `~` of the wrapped line
* Then it gets to the next line, which is being painted _before_ the
  client emits the rest of the line of text to fill that row.
* Conpty thinks this row is empty, (it is) and manually breaks the row.

However, the test expects this row to be emitted as wrapped. The problem
comes from the torn state in the middle of these frames - the original
line probably _should_ remain wrapped, but this is a sufficiently rare
case that the fix is being punted into the next release.

It's possible that improving how we handle line wrapping might also fix
this case - currently we're only marking a row as wrapped when we print
the last cell of a row, but we should probably mark it as wrapped
instead when we print the first char of the _following_ row. That work
is being tracked in #5800

### The real bug in this PR

The problem in the `DeleteWrappedWord` test is that the first line is
still being marked as wrapped. So when we get to painting the line below
it, we'll see that there are no characters to be printed (only spaces),
we emit a `^[20X^[20C`, but the cursor is still at the end of the first
line. Because it's there, we don't actually clear the text we want to
clear.

So DeleteWrappedWord, #5839 needs the `_wrappedRow = std::nullopt;`
statement here.

## References
* I guess just look at #5800, I put everything in there.

## Validation Steps Performed
* Tested manually that this was fixed for the Terminal
* ran tests

Closes #5839

(cherry picked from commit b4c33dd842)
2020-05-12 15:02:35 -07:00
Leon Liang
b9483a9471 Revert some emoji back to narrow width
A couple of codepoints, namely the card suites, male and female signs,
and white and black smiling faces were changed to have a two-column
width as part of #5795 since they were specified as emoji in Unicode's
emoji list v13.0[1].

These particular glyphs also show up in some of the most fundamental
code pages, such as CP437[2] and WGL4[3]. We should
not be touching the width of the glyphs in these codepages, as suddenly
changing a long-time-running narrow glyph to use two-columns all of a
sudden will surely break (and has already broken) things.

[1] https://www.unicode.org/Public/13.0.0/ucd/emoji/emoji-data.txt
[2] https://en.wikipedia.org/wiki/Code_page_437
[3] https://en.wikipedia.org/wiki/Windows_Glyph_List_4

Closes #5822

(cherry picked from commit cf62922ad8)
2020-05-12 12:39:40 -07:00
Dustin L. Howett (MSFT)
43266a2f3d Bump Cascadia Code to v2004.30 (#5867)
(cherry picked from commit f9ec9b7f2e)
2020-05-12 12:36:08 -07:00
Dustin L. Howett (MSFT)
c31c857c1b Teach TerminalPage to handle exceptions that happen during paste (#5856)
Terminal should try not to join the choir invisible when the clipboard
API straight up horks it.

This accounts for ~3% of the crashes seen in 1.0RC1 and ~1% of the
crashes seen all-up in the last 14 days.

## Repro (prior to this commit)
Set `"copyOnSelect": true`.

Copy something small.

Hold down <kbd>Ctrl+Shift+V</kbd>

Double-click like your life depends on it. Double-click like you're
playing cookie clicker again. 2013 called, it wants its cookies back.

Fixes #4906.

(cherry picked from commit a99c812794)
2020-05-12 11:24:28 -07:00
Dustin L. Howett (MSFT)
36c5b5b5dc Stop trying to set selection endpoints when there's no selection (#5855)
It turns out that we weren't really adequately guarding calls to
SetSelectionEnd and friends.

We're clearing the active selection when the window resizes, but we're
doing so by nulling out the std::optional<Selection> it lives in. Later,
though, when we set the selection endpoint we're using "_selection->".

Optional's operator-> has undefined behavior when the optional doesn't
have a value in it.

In our case, it looks like it was returning whatever the value was prior
to it being emptied out. PivotSelection would attempt to access an
out-of-bounds coordinate when the buffer got smaller during a resize.

The solution is to guard both levels of selection endpoint manipulation
in a check for an active selection.

Apparently, this accounts for somewhere between 7% and 14% of our
crashes on 1.0RC1.

Repro was:
Use Win+Arrow to snap the window while in the middle of a selection.

(cherry picked from commit fcd5bb39f0)
2020-05-12 11:24:28 -07:00
Dustin L. Howett (MSFT)
91fd1d0cbf InteractivityWin32: Add a dependency on Dx (#5851)
#5743 introduced a dependency from _any consumer of the DX header_ to a header generated from an IDL file.

Fixes #5819.

(cherry picked from commit e088f73671)
2020-05-12 11:24:28 -07:00
Michael Niksa
15e338a7cd Add renderer settings to mitigate blurry text for some graphics devices
## Summary of the Pull Request
Adds user settings to adjust rendering behavior to mitigate blurry text on some devices.

## References
- #778 introduced this, almost certainly.

## PR Checklist
* [x] Closes #5759, mostly
* [x] I work here.
* [ ] We need community verification that this will help.
* [x] Updated schema and schema doc.
* [x] Am core contributor. Discussed in Monday sync meeting and w/ @DHowett-MSFT.

## Detailed Description of the Pull Request / Additional comments
When we switched from full-screen repaints to incremental rendering, it seems like we exposed a situation where some display drivers and hardware combinations do not handle scroll and/or dirty regions (from `IDXGISwapChain::Present1`) without blurring the data from the previous frame. As we're really close to ship, I'm offering two options to let people in this situation escape it on their own. We hope in the future to figure out what's actually going on here and mitigate it further in software, but until then, these escape hatches are available.

1. `experimental.rendering.forceFullRepaint` - This one restores the pre-778 behavior to the Terminal. On every single frame paint, we'll invalidate the entire screen and repaint it.
2. `experimental.rendering.software` - This one uses the software WARP renderer instead of using the hardware and display driver directly. The theory is that this will sidestep any driver bugs or hardware variations.

One, the other, or both of these may be field-applied by users who are experiencing this behavior.

Reverting #778 completely would also resolve this, but it would give back our largest performance win in the whole Terminal project. We don't believe that's acceptable when seemingly a majority of the users are experiencing the performance benefit with no detriment to graphical display.

## Validation Steps Performed
- [x] Flipped them on and verified with the debugger that they are being applied to the rendering pipeline
- [ ] Gave a private copy to community members in #5759 and had them try whether one, the other, or both resolved their issue.

(cherry picked from commit d01317c9db)
2020-05-11 14:55:31 -07:00
Dustin L. Howett (MSFT)
12488968dc dx: when filling an HWND target, use the actual background color (#5848)
There is no guarantee that the HWND's backing color matches our expected
backing color.

This repairs the gutter in the WPF terminal.

(cherry picked from commit 177fd74584)
2020-05-11 13:55:10 -07:00
Dustin L. Howett (MSFT)
1085914d1f dx: fix a missing stdcall that was blowing up the x86 build (#5818)
(cherry picked from commit f701bd40c5)
2020-05-08 16:02:29 -07:00
Leon Liang
ef8e4bf753 Make most emojis full-width (#5795)
The table that we refer to in `CodepointWidthDetector.cpp` to determine
whether or not a codepoint should be rendered as Wide vs Narrow was
based off EastAsianWidth[1].  If a codepoint wasn't included in this
table, they're considered Narrow. Many emojis aren't specified in the
EAW list, so this PR supplements our table with emoji codepoints from
emoji-data[2] in order to render most, if not all, emojis as full-width.

There are certain codepoints I've added to the comments (in case we want
to add them officially to the table in the future) that Microsoft
decided to give an emoji presentation even if it's specified as
Narrow/Ambiguous in the EAW list and are _not_ specified in the Unicode
emoji list. These include all of the Mahjong Tiles block, different
direction pencils (✎✐), different pointing index fingers (☜, ☞) among
others. I have no idea if I've captured all of them, as I don't know of
an easy way to detect which are Microsoft specific emojis.

## Validation Steps Performed
I have looked at so many emojis that I dream emoji.

These screenshots aren't encompassing _all_ emoji but I've tried to grab
a couple from all across the codepoint ranges:

Before:
![before](https://user-images.githubusercontent.com/57155886/81445092-2051a980-912d-11ea-9739-c9f588da407d.png)

After:
![after](https://user-images.githubusercontent.com/57155886/81445107-2778b780-912d-11ea-9615-676c2150e798.png)

[1] http://www.unicode.org/Public/UCD/latest/ucd/EastAsianWidth.txt
[2] https://www.unicode.org/Public/13.0.0/ucd/emoji/emoji-data.txt

Closes #900

(cherry picked from commit 7ae34336da)
2020-05-08 15:32:11 -07:00
Carlos Zamora
8ece1378e5 Trigger scroll on scrolled selection (#5798)
## Summary of the Pull Request
We accidentally missed switching one `TriggerRedrawAll` to `TriggerScroll`. This does that.

## References
#5185 - applies logic from this PR

## PR Checklist
* [X] Closes #5756

## Validation Steps Performed
Followed bug repro steps.

(cherry picked from commit 75752aed80)
2020-05-08 14:55:18 -07:00
Mike Griese
2314df8798 Fix wrapped lines in less in Git for Windows (#5771)
## Summary of the Pull Request

This PR resolves an issue with the Git for Windows (MSYS) version of `less`. It _doesn't_ use VT processing for emitting text tothe buffer, so when it hits `WriteCharsLegacy`, `WC_DELAY_EOL_WRAP` is NOT set.

When this happens, `less` is writing some text that's longer than the width of the buffer to the last line of the buffer. We're hitting the
```c++
    Status = AdjustCursorPosition(screenInfo, CursorPosition, WI_IsFlagSet(dwFlags, WC_KEEP_CURSOR_VISIBLE), psScrollY);
```
call in `_stream.cpp:560`.

The cursor is _currently_ at `{40, 29}`, the _start_ of the run of text that wrapped. We're trying to adjust it to `{0, 30}`, which would be the start of the next line of the buffer. However, the buffer is only 30 lines tall, so we've got to `IncrementCircularBuffer` first, so we can move the cursor there.

When that happens, we're going to paint frame. At the end of that frame, we're going to try and paint the cursor position. The cursor is still at `{40, 29}` here, so unfortunately, the `cursorIsInDeferredWrap` check in `XtermEngine::PaintCursor` is `false`. That means, conpty is going to try to move the cursor to where the console thinks the cursor actually is at the end of this frame, which is `{40, 29}`.

If we're painting the frame because we circled the buffer, then the cursor might still be in the position it was before the text was written to the buffer to cause the buffer to circle. In that case, then we DON'T want to paint the cursor here either, because it'll cause us to manually break this line. That's okay though, the frame will be painted again, after the circling is complete.

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

## Detailed Description of the Pull Request / Additional comments

I suppose that's the detailed description above

## Validation Steps Performed
* ran tests
* checked that the bug was actually fixed in the Terminal

(cherry picked from commit 38472719d5)
2020-05-08 14:55:18 -07:00
Dustin L. Howett (MSFT)
a52a588141 build: merge the signing steps and wildcard them (#5817)
This allows me to make the build pipeline, instead of the release
engineer, put the version number in the package name.

It also lets us sign multiple packages (if we ever produce more than
one.)

(cherry picked from commit e3fdb1a1a3)
2020-05-08 14:11:27 -07:00
Michael Niksa
b1e4daaeed Scale box drawing glyphs to fit cells for visual bliss (#5743)
## Summary of the Pull Request
Identifies and scales glyphs in the box and line drawing ranges U+2500-U+259F to fit their cells.

## PR Checklist
* [x] Closes #455
* [x] I work here.
* [x] Manual tests. This is all graphical.
* [x] Metric ton of comments
* [x] Math spreadsheet included in PR.
* [x] Double check RTL glyphs.
* [x] Why is there the extra pixel?
* [x] Scrolling the mouse wheel check is done.
* [x] Not drawing outline?
* [x] Am core contributor. Roar.
* [x] Try suppressing negative scale factors and see if that gets rid of weird shading.

## Detailed Description of the Pull Request / Additional comments

### Background
- We want the Terminal to be fast at drawing. To be fast at drawing, we perform differential drawing, or only drawing what is different from the previous frame. We use DXGI's `Present1` method to help us with this as it helps us compose only the deltas onto the previous frame at drawing time and assists us in scrolling regions from the previous frame without intervention. However, it only works on strictly integer pixel row heights.
- Most of the hit testing and size-calculation logic in both the `conhost` and the Terminal products are based on the size of an individual cell. Historically, a cell was always dictated in a `COORD` structure, or two `SHORT` values... which are integers. As such, when we specify the space for any individual glyph to be displayed inside our terminal drawing region, we want it to fall perfectly inside of an integer box to ensure all these other algorithms work correctly and continue to do so.
- Finally, we want the Terminal to have font fallback and locate glyphs that aren't in the primary selected font from any other font it can find on the system that contains the glyph, per DirectWrite's font fallback mechanisms. These glyphs won't necessarily have the same font or glyph metrics as the base font, but we need them to fit inside the same cell dimensions as if they did because the hit testing and other algorithms aren't aware of which particular font is sourcing each glyph, just the dimensions of the bounding box per cell.

### How does Terminal deal with this?
- When we select a font, we perform some calculations using the design metrics of the font and glyphs to determine how we could fit them inside a cell with integer dimensions. Our process here is that we take the requested font size (which is generally a proxy for height), find the matching glyph width for that height then round it to an integer. We back convert from that now integer width to a height value which is almost certainly now a floating point number. But because we need an integer box value, we add line padding above and below the glyphs to ensure that the height is an integer as well as the width. Finally, we don't add the padding strictly equally. We attempt to align the English baseline of the glyph box directly onto an integer pixel multiple so most characters sit crisply on a line when displayed.
- Note that fonts and their glyphs have a prescribed baseline, line gap, and advance values. We use those as guidelines to get us started, but then to meet our requirements, we pad out from those. This results in fonts that should be properly authored showing gaps. It also results in fonts that are improperly authored looking even worse than they normally would.

### Now how does block and line drawing come in?
- Block and Line drawing glyphs are generally authored so they will look fine when the font and glyph metrics are followed exactly as prescribed by the font. (For some fonts, this still isn't true and we want them to look fine anyway.)
- When we add additional padding or rounding to make glyphs fit inside of a cell, we can be adding more space than was prescribed around these glyphs. This can cause a gap to be visible.
- Additionally, when we move things like baselines to land on a perfect integer pixel, we may be drawing a glyph lower in the bounding box than was prescribed originally.

### And how do we solve it?
- We identify all glyphs in the line and block drawing ranges.
- We find the bounding boxes of both the cell and the glyph.
- We compare the height of the glyph to the height of the cell to see if we need to scale. We prescribe a scale transform if the glyph wouldn't be tall enough to fit the box. (We leave it alone otherwise as some glyphs intentionally overscan the box and scaling them can cause banding effects.)
- We inspect the overhang/underhang above and below the boxes and translate transform them (slide them) so they cover the entire cell area.
- We repeat the previous two steps but in the horizontal direction.

## Validation Steps Performed
- See these commments:
   - https://github.com/microsoft/terminal/issues/455#issuecomment-620248375
   - https://github.com/microsoft/terminal/issues/455#issuecomment-621533916
   - https://github.com/microsoft/terminal/issues/455#issuecomment-622585453

Also see the below one with more screenshots:
   - https://github.com/microsoft/terminal/pull/5743#issuecomment-624940567

(cherry picked from commit 70867df077)
2020-05-08 14:11:27 -07:00
Carlos Zamora
e119959943 Add an AppDescription for the Preview package (#5794)
(cherry picked from commit 28dc8196ab)
2020-05-08 13:20:43 -07:00
Mike Griese
7b291ea39a Manually select a new tab when we're in fullscreen mode (#5809)
If we're fullscreen, the TabView isn't `Visible`. If it's not `Visible`,
it's _not_ going to raise a `SelectionChanged` event, which is what we
usually use to focus another tab. Instead, we'll have to do it manually
here.

So, what we're going to try to do is move the focus to the tab to the
left, within the bounds of how many tabs we have.

EX: we have 4 tabs: [A, B, C, D]. If we close:
* A (`tabIndex=0`): We'll want to focus tab B (now in index 0)
* B (`tabIndex=1`): We'll want to focus tab A (now in index 0)
* C (`tabIndex=2`): We'll want to focus tab B (now in index 1)
* D (`tabIndex=3`): We'll want to focus tab C (now in index 2)

`_UpdatedSelectedTab` will do the work of setting up the new tab as the
focused one, and unfocusing all the others.

Also, we need to _manually_ set the SelectedItem of the tabView here. If
we don't, then the TabView will technically not have a selected item at
all, which can make things like ClosePane not work correctly.

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

## Validation Steps Performed

Played with it a bunch

(cherry picked from commit d77745d035)
2020-05-08 12:58:17 -07:00
Carlos Zamora
d739523db2 Add a new appxmanifest for preview (#5774)
## Summary of the Pull Request
This adds a new appxmanifest for 'Windows Terminal (Preview)' and links the resources.

Code-wise, split up `WindowsTerminalReleaseBuild` into...
- WindowsTerminalOfficialBuild: [true, false]
- WindowsTerminalBranding: [Dev, Preview, Release]

Added a comment about that in release.yml

## Validation Steps Performed
used msbuild to build...
- [X] Dev
- [X] Preview
- [X] Release
then checked the msix for the correct name/icon.

(cherry picked from commit 9a927f3a0f)
2020-05-08 12:58:17 -07:00
Dustin L. Howett (MSFT)
04a172ed92 res: on second thought, tuck the lozenge in at smaller sizes (#5757)
(cherry picked from commit 9e1d2d2e63)
2020-05-08 12:58:16 -07:00
Dustin L. Howett (MSFT)
06640d3c51 Switch to the new lozenge-style dev icons and add preview icons (#5755)
This commit also introduces a copy of the svg source for the icon.

The icons were generated with a powershell script, which will be the
subject of a future checkin.

Below, peep the asset size ramps. The text is hidden at sizes <32px because it would be illegible. Click for full size, as they do not necessarily fit in the GitHub box.

![montage](https://user-images.githubusercontent.com/14316954/81114789-8c3ad480-8ed7-11ea-8963-67ba195f25b8.png)

![montage](https://user-images.githubusercontent.com/14316954/81114796-8f35c500-8ed7-11ea-881f-c69fc9468914.png)

(cherry picked from commit 0eaa7214ae)
2020-05-08 12:58:16 -07:00
Dustin L. Howett (MSFT)
cbc42caebb Make sure we don't try to remove tabs when they don't exist (#5742)
This was an oversight.

Fixes #5738.

(cherry picked from commit 046fed3d97)
2020-05-05 15:42:36 -07:00
Mike Griese
420a0c9245 Make sure that EraseAll moves the Terminal viewport (#5683)
The Erase All VT sequence (`^[[2J`) is supposed to erase the entire
contents of the viewport. The way it usually does this is by shifting
the entirety of the viewport contents into scrollback, and starting the
new viewport below it.

Currently, conpty doesn't propagate that state change correctly. When
conpty gets a 2J, it simply erases the content of the connected
terminal's viewport, by writing over it with spaces. Conpty didn't
really have a good way of communicating "your viewport should move", it
only knew "the buffer is now full of spaces".

This would lead to bugs like #2832, where pressing <kbd>ctrl+L</kbd> in
`bash` would delete the current contents of the viewport, instead of
moving the viewport down.

This PR makes sure that when conpty sees a 2J, it passes that through
directly to the connected terminal application as well. Fortunately, 2J
was already implemented in the Windows Terminal, so this actually fixes
the behavior of <kbd>ctrl+L</kbd>/`clear` in WSL in the Terminal.

## References

* #4252 - right now this isn't the _most_ optimal scenario, we're
  literally just printing a 2J, then we'll perform "erase line" `height`
  times. The erase line operations are all redundant at this point - the
  entire viewport is blank, but conpty doesn't really know that.
  Fortunately, #4252 was already filed for me to come through and
  optimize this path.

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

## Validation Steps Performed
* ran tests
* compared <kbd>ctrl+L</kbd> with its behavior in conhost
* compared `clear` with its behavior in conhost

(cherry picked from commit 9fe624ffbc)
2020-05-04 18:45:05 -07:00
189 changed files with 3082 additions and 3750 deletions

View File

@@ -125,7 +125,7 @@ Team members will be happy to help review specs and guide them to completion.
### Help Wanted
Once the team have approved an issue/spec, development can proceed. If no developers are immediately available, the spec can be parked ready for a developer to get started. Parked specs' issues will be labeled "Help Wanted". To find a list of development opportunities waiting for developer involvement, visit the Issues and filter on [the Help-Wanted label](https://github.com/microsoft/terminal/labels/Help%20Wanted).
Once the team have approved an issue/spec, development can proceed. If no developers are immediately available, the spec can be parked ready for a developer to get started. Parked specs' issues will be labeled "Help Wanted". To find a list of development opportunities waiting for developer involvement, visit the Issues and filter on [the Help-Wanted label](https://github.com/microsoft/terminal/labels/Help-Wanted).
---
@@ -155,4 +155,4 @@ Once your code has been reviewed and approved by the requisite number of team me
## Thank you
Thank you in advance for your contribution! Now, [what's next on the list](https://github.com/microsoft/terminal/labels/Help%20Wanted)? 😜
Thank you in advance for your contribution! Now, [what's next on the list](https://github.com/microsoft/terminal/labels/Help-Wanted)? 😜

View File

@@ -231,7 +231,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTests_TerminalApp", "sr
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalAppLib", "src\cascadia\TerminalApp\lib\TerminalAppLib.vcxproj", "{CA5CAD1A-9A12-429C-B551-8562EC954746}"
ProjectSection(ProjectDependencies) = postProject
{CA5CAD1A-0A1E-4F38-8704-9BFF1C37AA92} = {CA5CAD1A-0A1E-4F38-8704-9BFF1C37AA92}
{CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED} = {CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED}
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907} = {CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}
EndProjectSection
@@ -303,8 +302,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalAzBridge", "src\cas
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fmt", "src\dep\fmt\fmt.vcxproj", "{6BAE5851-50D5-4934-8D5E-30361A8A40F3}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalSettingsControl", "src\cascadia\TerminalSettingsControl\TerminalSettingsControl.vcxproj", "{CA5CAD1A-0A1E-4F38-8704-9BFF1C37AA92}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
AuditMode|Any CPU = AuditMode|Any CPU
@@ -1511,27 +1508,6 @@ Global
{6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Release|x64.Build.0 = Release|x64
{6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Release|x86.ActiveCfg = Release|Win32
{6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Release|x86.Build.0 = Release|Win32
{CA5CAD1A-0A1E-4F38-8704-9BFF1C37AA92}.AuditMode|Any CPU.ActiveCfg = AuditMode|Win32
{CA5CAD1A-0A1E-4F38-8704-9BFF1C37AA92}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
{CA5CAD1A-0A1E-4F38-8704-9BFF1C37AA92}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
{CA5CAD1A-0A1E-4F38-8704-9BFF1C37AA92}.AuditMode|x64.ActiveCfg = AuditMode|x64
{CA5CAD1A-0A1E-4F38-8704-9BFF1C37AA92}.AuditMode|x64.Build.0 = AuditMode|x64
{CA5CAD1A-0A1E-4F38-8704-9BFF1C37AA92}.AuditMode|x86.ActiveCfg = AuditMode|Win32
{CA5CAD1A-0A1E-4F38-8704-9BFF1C37AA92}.AuditMode|x86.Build.0 = AuditMode|Win32
{CA5CAD1A-0A1E-4F38-8704-9BFF1C37AA92}.Debug|Any CPU.ActiveCfg = Debug|Win32
{CA5CAD1A-0A1E-4F38-8704-9BFF1C37AA92}.Debug|ARM64.ActiveCfg = Debug|ARM64
{CA5CAD1A-0A1E-4F38-8704-9BFF1C37AA92}.Debug|ARM64.Build.0 = Debug|ARM64
{CA5CAD1A-0A1E-4F38-8704-9BFF1C37AA92}.Debug|x64.ActiveCfg = Debug|x64
{CA5CAD1A-0A1E-4F38-8704-9BFF1C37AA92}.Debug|x64.Build.0 = Debug|x64
{CA5CAD1A-0A1E-4F38-8704-9BFF1C37AA92}.Debug|x86.ActiveCfg = Debug|Win32
{CA5CAD1A-0A1E-4F38-8704-9BFF1C37AA92}.Debug|x86.Build.0 = Debug|Win32
{CA5CAD1A-0A1E-4F38-8704-9BFF1C37AA92}.Release|Any CPU.ActiveCfg = Release|Win32
{CA5CAD1A-0A1E-4F38-8704-9BFF1C37AA92}.Release|ARM64.ActiveCfg = Release|ARM64
{CA5CAD1A-0A1E-4F38-8704-9BFF1C37AA92}.Release|ARM64.Build.0 = Release|ARM64
{CA5CAD1A-0A1E-4F38-8704-9BFF1C37AA92}.Release|x64.ActiveCfg = Release|x64
{CA5CAD1A-0A1E-4F38-8704-9BFF1C37AA92}.Release|x64.Build.0 = Release|x64
{CA5CAD1A-0A1E-4F38-8704-9BFF1C37AA92}.Release|x86.ActiveCfg = Release|Win32
{CA5CAD1A-0A1E-4F38-8704-9BFF1C37AA92}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1610,7 +1586,6 @@ Global
{024052DE-83FB-4653-AEA4-90790D29D5BD} = {E8F24881-5E37-4362-B191-A3BA0ED7F4EB}
{067F0A06-FCB7-472C-96E9-B03B54E8E18D} = {59840756-302F-44DF-AA47-441A9D673202}
{6BAE5851-50D5-4934-8D5E-30361A8A40F3} = {81C352DB-1818-45B7-A284-18E259F1CC87}
{CA5CAD1A-0A1E-4F38-8704-9BFF1C37AA92} = {59840756-302F-44DF-AA47-441A9D673202}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3140B1B7-C8EE-43D1-A772-D82A7061A271}

View File

@@ -2,8 +2,7 @@
This repository contains the source code for:
* [Windows Terminal](https://aka.ms/terminal)
* [Windows Terminal Preview](https://aka.ms/terminal-preview)
* [Windows Terminal](https://www.microsoft.com/en-us/p/windows-terminal-preview/9n0dx20hk701)
* The Windows console host (`conhost.exe`)
* Components shared between the two projects
* [ColorTool](https://github.com/Microsoft/Terminal/tree/master/src/tools/ColorTool)
@@ -11,7 +10,6 @@ This repository contains the source code for:
Related repositories include:
* [Windows Terminal Documentation](https://docs.microsoft.com/windows/terminal) ([Repo: Contribute to the docs](https://github.com/MicrosoftDocs/terminal))
* [Console API Documentation](https://github.com/MicrosoftDocs/Console-Docs)
* [Cascadia Code Font](https://github.com/Microsoft/Cascadia-Code)
@@ -21,7 +19,7 @@ Related repositories include:
### Microsoft Store [Recommended]
Install the [Windows Terminal from the Microsoft Store][store-install-link]. This allows you to always be on the latest version when we release new builds with automatic upgrades.
Install the [Windows Terminal from the Microsoft Store][store-install-link]. This allows you to always be on the latest version when we release new builds with automatic upgrades.
This is our preferred method.
@@ -36,14 +34,6 @@ For users who are unable to install Terminal from the Microsoft Store, Terminal
> * Be sure to install the [Desktop Bridge VC++ v14 Redistributable Package](https://www.microsoft.com/en-us/download/details.aspx?id=53175) otherwise Terminal may not install and/or run and may crash at startup
> * 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!
#### Via Windows Package Manager CLI (aka winget)
[winget](https://github.com/microsoft/winget-cli) users can download and install the latest Terminal release by installing the `Microsoft.WindowsTerminal` package:
```powershell
winget install --id=Microsoft.WindowsTerminal -e
```
#### Via Chocolatey (unofficial)
[Chocolatey](https://chocolatey.org) users can download and install the latest Terminal release by installing the `microsoft-windows-terminal` package:
@@ -71,6 +61,12 @@ ColorTool|![](https://microsoft.visualstudio.com/_apis/public/build/definitions/
---
## Windows Terminal v1.0 Roadmap
The plan for delivering Windows Terminal v1.0 [is described here](/doc/terminal-v1-roadmap.md), and will be updated as the project proceeds.
---
## Terminal & Console Overview
Please take a few minutes to review the overview below before diving into the code:
@@ -135,7 +131,7 @@ Solution: Make sure you're building & deploying the `CascadiaPackage` project in
## Documentation
All project documentation is located at aka.ms/terminal-docs. If you would like to contribute to the documentation, please submit a pull request on the [Windows Terminal Documentation repo](https://github.com/MicrosoftDocs/terminal).
All project documentation is located in the `./doc` folder. If you would like to contribute to the documentation, please submit a pull request.
---
@@ -230,4 +226,4 @@ For more information see the [Code of Conduct FAQ][conduct-FAQ] or contact [open
[conduct-code]: https://opensource.microsoft.com/codeofconduct/
[conduct-FAQ]: https://opensource.microsoft.com/codeofconduct/faq/
[conduct-email]: mailto:opencode@microsoft.com
[store-install-link]: https://aka.ms/terminal
[store-install-link]: https://aka.ms/windowsterminal

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
</PropertyGroup>
<Target Name="BeforeGenerateProjectPriFile" DependsOnTargets="OpenConsoleCollectWildcardPRIFiles" />
<!--
The vcxproj system does not support wildcards at the root level of a project.
This poses a problem, as we want to include resw files that are not checked into the
repository. Since they're usually localized and stored in directories named after
their languages, we can't exactly explicitly simultaneously list them all and remain
sane. We want to use wildcards to make our lives easier.
This rule takes OCResourceDirectory items and includes all resw files that live
underneath them.
** TIRED **
(does not work because of wildcards)
<PRIResource Include="Resources/*/Resources.resw" />
** WIRED **
(keep the en-US resource in the project, because it is checked in and VS will show it)
<PRIResource Include="Resources/en-US/Resources.resw" />
<OCResourceDirectory Include="Resources" />
-->
<Target Name="OpenConsoleCollectWildcardPRIFiles">
<CreateItem Include="@(OCResourceDirectory->'%(Identity)\**\*.resw')">
<Output TaskParameter="Include" ItemName="_OCFoundPRIFiles" />
</CreateItem>
<ItemGroup>
<_OCFoundPRIFiles Include="@(PRIResource)" />
<PRIResource Remove="@(PRIResource)" />
<PRIResource Include="@(_OCFoundPRIFiles->Distinct())" />
</ItemGroup>
<Message Text="$(ProjectName) (wildcard PRIs) -> @(PRIResource)" />
</Target>
</Project>

View File

@@ -5,7 +5,7 @@
<XesUseOneStoreVersioning>true</XesUseOneStoreVersioning>
<XesBaseYearForStoreVersion>2020</XesBaseYearForStoreVersion>
<VersionMajor>1</VersionMajor>
<VersionMinor>1</VersionMinor>
<VersionMinor>0</VersionMinor>
<VersionInfoProductName>Windows Terminal</VersionInfoProductName>
</PropertyGroup>
</Project>

Submodule dep/wil updated: e8c599bca6...3c00e7f1d8

View File

@@ -47,7 +47,6 @@ Properties listed below are specific to each unique profile.
| `cursorShape` | Optional | String | `bar` | Sets the cursor shape for the profile. Possible values: `"vintage"` ( &#x2583; ), `"bar"` ( &#x2503; ), `"underscore"` ( &#x2581; ), `"filledBox"` ( &#x2588; ), `"emptyBox"` ( &#x25AF; ) |
| `fontFace` | Optional | String | `Cascadia Mono` | Name of the font face used in the profile. We will try to fallback to Consolas if this can't be found or is invalid. |
| `fontSize` | Optional | Integer | `12` | Sets the font size. |
| `fontWeight` | Optional | String | `normal` | Sets the weight (lightness or heaviness of the strokes) for the given font. Possible values: `"thin"`, `"extra-light"`, `"light"`, `"semi-light"`, `"normal"`, `"medium"`, `"semi-bold"`, `"bold"`, `"extra-bold"`, `"black"`, `"extra-black"`, or the corresponding numeric representation of OpenType font weight. |
| `foreground` | Optional | String | | Sets the foreground color of the profile. Overrides `foreground` set in color scheme if `colorscheme` is set. Uses hex color format: `#rgb` or `"#rrggbb"`. |
| `hidden` | Optional | Boolean | `false` | If set to true, the profile will not appear in the list of profiles. This can be used to hide default profiles and dynamically generated profiles, while leaving them in your settings file. |
| `historySize` | Optional | Integer | `9001` | The number of lines above the ones displayed in the window you can scroll back to. |

View File

@@ -531,32 +531,6 @@
"minimum": 1,
"type": "integer"
},
"fontWeight": {
"default": "normal",
"description": "Sets the weight (lightness or heaviness of the strokes) for the given font. Possible values:\n -\"thin\"\n -\"extra-light\"\n -\"light\"\n -\"semi-light\"\n -\"normal\" (default)\n -\"medium\"\n -\"semi-bold\"\n -\"bold\"\n -\"extra-bold\"\n -\"black\"\n -\"extra-black\" or the corresponding numeric representation of OpenType font weight.",
"oneOf": [
{
"enum": [
"thin",
"extra-light",
"light",
"semi-light",
"normal",
"medium",
"semi-bold",
"bold",
"extra-bold",
"black",
"extra-black"
],
"type": "string"
},
{
"maximum": 990,
"minimum": 100,
"type": "integer"
}
}
"foreground": {
"$ref": "#/definitions/Color",
"default": "#cccccc",

View File

@@ -88,7 +88,7 @@ This will allow you to simplify the above snippet as follows:
}
```
A list of default key bindings is available [here](https://github.com/microsoft/terminal/blob/master/src/cascadia/TerminalApp/defaults.json#L204).
### Unbinding keys
@@ -160,7 +160,7 @@ Example settings include
The profile GUID is used to reference the default profile in the global settings.
The values for background image stretch mode are documented [here](https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.media.stretch).
The values for background image stretch mode are documented [here](https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.media.stretch)
### Hiding a profile

View File

@@ -25,7 +25,7 @@ NOTE: The default shell is PowerShell; you can change this using the _Running a
### Command line options
Windows Terminal has implemented a rich set of command-line options in part as response to issue [#607](https://github.com/microsoft/terminal/issues/607). See [UsingCommandlineArguments.md](https://github.com/microsoft/terminal/blob/master/doc/user-docs/UsingCommandlineArguments.md) for details.
None at this time. See issue [#607](https://github.com/microsoft/terminal/issues/607)
## Multiple Tabs
@@ -45,7 +45,7 @@ To customize the shell list, see the _Configuring Windows Terminal_ section belo
## Starting a new PowerShell tab with admin privilege
There is no current plan to support this feature for security reasons. See issue [#632](https://github.com/microsoft/terminal/issues/632)
There is no current plan to support this feature for security reasons. See issue [#623](https://github.com/microsoft/terminal/issues/632)
## Selecting and Copying Text in Windows Terminal
@@ -61,7 +61,7 @@ Copy and paste operations can also be keybound. For more information on how to b
## Add a "Open Windows Terminal Here" to File Explorer
Not currently supported "out of the box" (See issue [#1060](https://github.com/microsoft/terminal/issues/1060)). However, you can open Windows Terminal in current directory by typing `wt -d .` in the Explorer address bar.
Not currently supported "out of the box". See issue [#1060](https://github.com/microsoft/terminal/issues/1060)
## Configuring Windows Terminal
@@ -87,5 +87,4 @@ For an introduction to the various settings, see [Using Json Settings](UsingJson
2. Terminal zoom can be changed by holding <kbd>Ctrl</kbd> and scrolling with mouse.
3. Background opacity can be changed by holding <kbd>Ctrl</kbd>+<kbd>Shift</kbd> and scrolling with mouse. Note that acrylic transparency is limited by the OS only to focused windows.
4. Open Windows Terminal in current directory by typing `wt -d .` in the address bar.
5. Pin the Windows Terminal to the taskbar. Now it can be launched using the Windows shortcut <kbd>Win</kbd>+<kbd>Number</kbd> (e.g. <kbd>Win</kbd>+<kbd>1</kbd> or any other number based on the position in the taskbar!). Press <kbd>Win</kbd>+<kbd>Shift</kbd>+<kbd>Number</kbd> to always launch a new window.
6. Please add more Tips and Tricks.
5. Please add more Tips and Tricks.

Binary file not shown.

Binary file not shown.

View File

@@ -17,5 +17,5 @@ Please consult the [license](https://raw.githubusercontent.com/microsoft/cascadi
### Fonts Included
* Cascadia Code, Cascadia Mono (2005.15)
* from microsoft/cascadia-code@0610f2df4356200adb93cb5bca2221b92ad6ee7e
* Cascadia Code, Cascadia Mono (2007.01)
* from microsoft/cascadia-code@311cc603f30635da704b6a7d13050e245e61667b

View File

@@ -190,6 +190,26 @@ bool ATTR_ROW::SetAttrToEnd(const UINT iStart, const TextAttribute attr)
return SUCCEEDED(InsertAttrRuns({ &run, 1 }, iStart, _cchRowWidth - 1, _cchRowWidth));
}
// Routine Description:
// - Replaces all runs in the row with the given wToBeReplacedAttr with the new
// attribute wReplaceWith. This method is used for replacing specifically
// legacy attributes.
// Arguments:
// - wToBeReplacedAttr - the legacy attribute to replace in this row.
// - wReplaceWith - the new value for the matching runs' attributes.
// Return Value:
// <none>
void ATTR_ROW::ReplaceLegacyAttrs(_In_ WORD wToBeReplacedAttr, _In_ WORD wReplaceWith) noexcept
{
TextAttribute ToBeReplaced;
ToBeReplaced.SetFromLegacy(wToBeReplacedAttr);
TextAttribute ReplaceWith;
ReplaceWith.SetFromLegacy(wReplaceWith);
ReplaceAttrs(ToBeReplaced, ReplaceWith);
}
// Method Description:
// - Replaces all runs in the row with the given toBeReplacedAttr with the new
// attribute replaceWith.

View File

@@ -42,6 +42,7 @@ public:
size_t* const pApplies) const;
bool SetAttrToEnd(const UINT iStart, const TextAttribute attr);
void ReplaceLegacyAttrs(const WORD wToBeReplacedAttr, const WORD wReplaceWith) noexcept;
void ReplaceAttrs(const TextAttribute& toBeReplacedAttr, const TextAttribute& replaceWith) noexcept;
void Resize(const size_t newWidth);

View File

@@ -321,7 +321,7 @@ COORD CharRow::GetStorageKey(const size_t column) const noexcept
// - Updates the pointer to the parent row (which might change if we shuffle the rows around)
// Arguments:
// - pParent - Pointer to the parent row
void CharRow::UpdateParent(ROW* const pParent) noexcept
void CharRow::UpdateParent(ROW* const pParent)
{
_pParent = FAIL_FAST_IF_NULL(pParent);
}

View File

@@ -88,7 +88,7 @@ public:
const UnicodeStorage& GetUnicodeStorage() const noexcept;
COORD GetStorageKey(const size_t column) const noexcept;
void UpdateParent(ROW* const pParent) noexcept;
void UpdateParent(ROW* const pParent);
friend CharRowCellReference;
friend constexpr bool operator==(const CharRow& a, const CharRow& b) noexcept;

View File

@@ -44,6 +44,15 @@ OutputCell::OutputCell(const std::wstring_view charData,
_setFromStringView(charData);
}
OutputCell::OutputCell(const CHAR_INFO& charInfo) :
_text{ UNICODE_INVALID },
_dbcsAttribute{},
_textAttribute{ InvalidTextAttribute },
_behavior{ TextAttributeBehavior::Stored }
{
_setFromCharInfo(charInfo);
}
OutputCell::OutputCell(const OutputCellView& cell)
{
_setFromOutputCellView(cell);
@@ -75,6 +84,23 @@ void OutputCell::_setFromBehavior(const TextAttributeBehavior behavior)
THROW_HR_IF(E_INVALIDARG, behavior == TextAttributeBehavior::Stored);
}
void OutputCell::_setFromCharInfo(const CHAR_INFO& charInfo)
{
_text = charInfo.Char.UnicodeChar;
if (WI_IsFlagSet(charInfo.Attributes, COMMON_LVB_LEADING_BYTE))
{
_dbcsAttribute.SetLeading();
}
else if (WI_IsFlagSet(charInfo.Attributes, COMMON_LVB_TRAILING_BYTE))
{
_dbcsAttribute.SetTrailing();
}
_textAttribute.SetFromLegacy(charInfo.Attributes);
_behavior = TextAttributeBehavior::Stored;
}
void OutputCell::_setFromStringView(const std::wstring_view view)
{
_text = view;

View File

@@ -44,6 +44,7 @@ public:
const DbcsAttribute dbcsAttribute,
const TextAttribute textAttribute);
OutputCell(const CHAR_INFO& charInfo);
OutputCell(const OutputCellView& view);
OutputCell(const OutputCell&) = default;
@@ -85,6 +86,7 @@ private:
TextAttributeBehavior _behavior;
void _setFromBehavior(const TextAttributeBehavior behavior);
void _setFromCharInfo(const CHAR_INFO& charInfo);
void _setFromStringView(const std::wstring_view view);
void _setFromOutputCellView(const OutputCellView& cell);
};

View File

@@ -518,7 +518,8 @@ OutputCellView OutputCellIterator::s_GenerateView(const CHAR_INFO& charInfo) noe
dbcsAttr.SetTrailing();
}
const TextAttribute textAttr(charInfo.Attributes);
TextAttribute textAttr;
textAttr.SetFromLegacy(charInfo.Attributes);
const auto behavior = TextAttributeBehavior::Stored;
return OutputCellView(glyph, dbcsAttr, textAttr, behavior);

View File

@@ -18,7 +18,7 @@ COLORREF TextAttribute::CalculateRgbForeground(std::basic_string_view<COLORREF>
COLORREF defaultFgColor,
COLORREF defaultBgColor) const noexcept
{
return IsReverseVideo() ? _GetRgbBackground(colorTable, defaultBgColor) : _GetRgbForeground(colorTable, defaultFgColor);
return _IsReverseVideo() ? _GetRgbBackground(colorTable, defaultBgColor) : _GetRgbForeground(colorTable, defaultFgColor);
}
// Routine Description:
@@ -31,7 +31,7 @@ COLORREF TextAttribute::CalculateRgbBackground(std::basic_string_view<COLORREF>
COLORREF defaultFgColor,
COLORREF defaultBgColor) const noexcept
{
return IsReverseVideo() ? _GetRgbForeground(colorTable, defaultFgColor) : _GetRgbBackground(colorTable, defaultBgColor);
return _IsReverseVideo() ? _GetRgbForeground(colorTable, defaultFgColor) : _GetRgbBackground(colorTable, defaultBgColor);
}
// Routine Description:
@@ -60,6 +60,21 @@ COLORREF TextAttribute::_GetRgbBackground(std::basic_string_view<COLORREF> color
return _background.GetColor(colorTable, defaultColor, false);
}
void TextAttribute::SetMetaAttributes(const WORD wMeta) noexcept
{
WI_UpdateFlagsInMask(_wAttrLegacy, META_ATTRS, wMeta);
WI_ClearAllFlags(_wAttrLegacy, COMMON_LVB_SBCSDBCS);
}
WORD TextAttribute::GetMetaAttributes() const noexcept
{
WORD wMeta = _wAttrLegacy;
WI_ClearAllFlags(wMeta, FG_ATTRS);
WI_ClearAllFlags(wMeta, BG_ATTRS);
WI_ClearAllFlags(wMeta, COMMON_LVB_SBCSDBCS);
return wMeta;
}
void TextAttribute::SetForeground(const COLORREF rgbForeground) noexcept
{
_foreground = TextColor(rgbForeground);
@@ -70,14 +85,62 @@ void TextAttribute::SetBackground(const COLORREF rgbBackground) noexcept
_background = TextColor(rgbBackground);
}
void TextAttribute::SetIndexedForeground(const BYTE fgIndex) noexcept
void TextAttribute::SetFromLegacy(const WORD wLegacy) noexcept
{
_wAttrLegacy = gsl::narrow_cast<WORD>(wLegacy & META_ATTRS);
WI_ClearAllFlags(_wAttrLegacy, COMMON_LVB_SBCSDBCS);
const BYTE fgIndex = gsl::narrow_cast<BYTE>(wLegacy & FG_ATTRS);
const BYTE bgIndex = gsl::narrow_cast<BYTE>(wLegacy & BG_ATTRS) >> 4;
_foreground = TextColor(fgIndex);
_background = TextColor(bgIndex);
}
void TextAttribute::SetIndexedBackground(const BYTE bgIndex) noexcept
void TextAttribute::SetLegacyAttributes(const WORD attrs,
const bool setForeground,
const bool setBackground,
const bool setMeta) noexcept
{
_background = TextColor(bgIndex);
if (setForeground)
{
const BYTE fgIndex = gsl::narrow_cast<BYTE>(attrs & FG_ATTRS);
_foreground = TextColor(fgIndex);
}
if (setBackground)
{
const BYTE bgIndex = gsl::narrow_cast<BYTE>(attrs & BG_ATTRS) >> 4;
_background = TextColor(bgIndex);
}
if (setMeta)
{
SetMetaAttributes(attrs);
}
}
// Method Description:
// - Sets the foreground and/or background to a particular index in the 256color
// table. If either parameter is nullptr, it's ignored.
// This method can be used to set the colors to indexes in the range [0, 255],
// as opposed to SetLegacyAttributes, which clamps them to [0,15]
// Arguments:
// - foreground: nullptr if we should ignore this attr, else a pointer to a byte
// value to use as an index into the 256-color table.
// - background: nullptr if we should ignore this attr, else a pointer to a byte
// value to use as an index into the 256-color table.
// Return Value:
// - <none>
void TextAttribute::SetIndexedAttributes(const std::optional<const BYTE> foreground,
const std::optional<const BYTE> background) noexcept
{
if (foreground)
{
const BYTE fgIndex = (*foreground) & 0xFF;
_foreground = TextColor(fgIndex);
}
if (background)
{
const BYTE bgIndex = (*background) & 0xFF;
_background = TextColor(bgIndex);
}
}
void TextAttribute::SetColor(const COLORREF rgbColor, const bool fIsForeground) noexcept
@@ -132,81 +195,19 @@ void TextAttribute::SetRightVerticalDisplayed(const bool isDisplayed) noexcept
WI_UpdateFlag(_wAttrLegacy, COMMON_LVB_GRID_RVERTICAL, isDisplayed);
}
bool TextAttribute::IsBold() const noexcept
void TextAttribute::Embolden() noexcept
{
return WI_IsFlagSet(_extendedAttrs, ExtendedAttributes::Bold);
_SetBoldness(true);
}
bool TextAttribute::IsItalic() const noexcept
void TextAttribute::Debolden() noexcept
{
return WI_IsFlagSet(_extendedAttrs, ExtendedAttributes::Italics);
_SetBoldness(false);
}
bool TextAttribute::IsBlinking() const noexcept
void TextAttribute::SetExtendedAttributes(const ExtendedAttributes attrs) noexcept
{
return WI_IsFlagSet(_extendedAttrs, ExtendedAttributes::Blinking);
}
bool TextAttribute::IsInvisible() const noexcept
{
return WI_IsFlagSet(_extendedAttrs, ExtendedAttributes::Invisible);
}
bool TextAttribute::IsCrossedOut() const noexcept
{
return WI_IsFlagSet(_extendedAttrs, ExtendedAttributes::CrossedOut);
}
bool TextAttribute::IsUnderlined() const noexcept
{
// TODO:GH#2915 Treat underline separately from LVB_UNDERSCORE
return WI_IsFlagSet(_wAttrLegacy, COMMON_LVB_UNDERSCORE);
}
bool TextAttribute::IsReverseVideo() const noexcept
{
return WI_IsFlagSet(_wAttrLegacy, COMMON_LVB_REVERSE_VIDEO);
}
void TextAttribute::SetBold(bool isBold) noexcept
{
WI_UpdateFlag(_extendedAttrs, ExtendedAttributes::Bold, isBold);
}
void TextAttribute::SetItalics(bool isItalic) noexcept
{
WI_UpdateFlag(_extendedAttrs, ExtendedAttributes::Italics, isItalic);
}
void TextAttribute::SetBlinking(bool isBlinking) noexcept
{
WI_UpdateFlag(_extendedAttrs, ExtendedAttributes::Blinking, isBlinking);
}
void TextAttribute::SetInvisible(bool isInvisible) noexcept
{
WI_UpdateFlag(_extendedAttrs, ExtendedAttributes::Invisible, isInvisible);
}
void TextAttribute::SetCrossedOut(bool isCrossedOut) noexcept
{
WI_UpdateFlag(_extendedAttrs, ExtendedAttributes::CrossedOut, isCrossedOut);
}
void TextAttribute::SetUnderline(bool isUnderlined) noexcept
{
// TODO:GH#2915 Treat underline separately from LVB_UNDERSCORE
WI_UpdateFlag(_wAttrLegacy, COMMON_LVB_UNDERSCORE, isUnderlined);
}
void TextAttribute::SetReverseVideo(bool isReversed) noexcept
{
WI_UpdateFlag(_wAttrLegacy, COMMON_LVB_REVERSE_VIDEO, isReversed);
}
ExtendedAttributes TextAttribute::GetExtendedAttributes() const noexcept
{
return _extendedAttrs;
_extendedAttrs = attrs;
}
// Routine Description:
@@ -216,6 +217,11 @@ void TextAttribute::Invert() noexcept
WI_ToggleFlag(_wAttrLegacy, COMMON_LVB_REVERSE_VIDEO);
}
void TextAttribute::_SetBoldness(const bool isBold) noexcept
{
WI_UpdateFlag(_extendedAttrs, ExtendedAttributes::Bold, isBold);
}
void TextAttribute::SetDefaultForeground() noexcept
{
_foreground = TextColor();
@@ -261,6 +267,6 @@ bool TextAttribute::BackgroundIsDefault() const noexcept
// requires for most erasing and filling operations.
void TextAttribute::SetStandardErase() noexcept
{
_extendedAttrs = ExtendedAttributes::Normal;
_wAttrLegacy = 0;
SetExtendedAttributes(ExtendedAttributes::Normal);
SetMetaAttributes(0);
}

View File

@@ -107,6 +107,22 @@ public:
void SetLeftVerticalDisplayed(const bool isDisplayed) noexcept;
void SetRightVerticalDisplayed(const bool isDisplayed) noexcept;
void SetFromLegacy(const WORD wLegacy) noexcept;
void SetLegacyAttributes(const WORD attrs,
const bool setForeground,
const bool setBackground,
const bool setMeta) noexcept;
void SetIndexedAttributes(const std::optional<const BYTE> foreground,
const std::optional<const BYTE> background) noexcept;
void SetMetaAttributes(const WORD wMeta) noexcept;
WORD GetMetaAttributes() const noexcept;
void Embolden() noexcept;
void Debolden() noexcept;
void Invert() noexcept;
friend constexpr bool operator==(const TextAttribute& a, const TextAttribute& b) noexcept;
@@ -117,28 +133,21 @@ public:
friend constexpr bool operator!=(const WORD& legacyAttr, const TextAttribute& attr) noexcept;
bool IsLegacy() const noexcept;
bool IsBold() const noexcept;
bool IsItalic() const noexcept;
bool IsBlinking() const noexcept;
bool IsInvisible() const noexcept;
bool IsCrossedOut() const noexcept;
bool IsUnderlined() const noexcept;
bool IsReverseVideo() const noexcept;
void SetBold(bool isBold) noexcept;
void SetItalics(bool isItalic) noexcept;
void SetBlinking(bool isBlinking) noexcept;
void SetInvisible(bool isInvisible) noexcept;
void SetCrossedOut(bool isCrossedOut) noexcept;
void SetUnderline(bool isUnderlined) noexcept;
void SetReverseVideo(bool isReversed) noexcept;
constexpr bool IsBold() const noexcept
{
return WI_IsFlagSet(_extendedAttrs, ExtendedAttributes::Bold);
}
ExtendedAttributes GetExtendedAttributes() const noexcept;
constexpr ExtendedAttributes GetExtendedAttributes() const noexcept
{
return _extendedAttrs;
}
void SetExtendedAttributes(const ExtendedAttributes attrs) noexcept;
void SetForeground(const COLORREF rgbForeground) noexcept;
void SetBackground(const COLORREF rgbBackground) noexcept;
void SetIndexedForeground(const BYTE fgIndex) noexcept;
void SetIndexedBackground(const BYTE bgIndex) noexcept;
void SetColor(const COLORREF rgbColor, const bool fIsForeground) noexcept;
void SetDefaultForeground() noexcept;
@@ -156,13 +165,13 @@ public:
// This returns whether this attribute, if printed directly next to another attribute, for the space
// character, would look identical to the other one.
bool HasIdenticalVisualRepresentationForBlankSpace(const TextAttribute& other, const bool inverted = false) const noexcept
constexpr bool HasIdenticalVisualRepresentationForBlankSpace(const TextAttribute& other, const bool inverted = false) const noexcept
{
// sneaky-sneaky: I'm using xor here
// inverted is whether there's a global invert; Reverse is a local one.
// global ^ local == true : the background attribute is actually the visible foreground, so we care about the foregrounds being identical
// global ^ local == false: the foreground attribute is the visible foreground, so we care about the backgrounds being identical
const auto checkForeground = (inverted != IsReverseVideo());
const auto checkForeground = (inverted != _IsReverseVideo());
return !IsAnyGridLineEnabled() && // grid lines have a visual representation
// crossed out, doubly and singly underlined have a visual representation
WI_AreAllFlagsClear(_extendedAttrs, ExtendedAttributes::CrossedOut | ExtendedAttributes::DoublyUnderlined | ExtendedAttributes::Underlined) &&
@@ -184,6 +193,13 @@ private:
COLORREF _GetRgbBackground(std::basic_string_view<COLORREF> colorTable,
COLORREF defaultColor) const noexcept;
constexpr bool _IsReverseVideo() const noexcept
{
return WI_IsFlagSet(_wAttrLegacy, COMMON_LVB_REVERSE_VIDEO);
}
void _SetBoldness(const bool isBold) noexcept;
WORD _wAttrLegacy;
TextColor _foreground;
TextColor _background;

View File

@@ -45,3 +45,14 @@ void TextAttributeRun::SetAttributes(const TextAttribute textAttribute) noexcept
{
_attributes = textAttribute;
}
// Routine Description:
// - Sets the attributes of this run to the given legacy attributes
// Arguments:
// - wNew - the new value for this run's attributes
// Return Value:
// <none>
void TextAttributeRun::SetAttributesFromLegacy(const WORD wNew) noexcept
{
_attributes.SetFromLegacy(wNew);
}

View File

@@ -35,6 +35,7 @@ public:
const TextAttribute& GetAttributes() const noexcept;
void SetAttributes(const TextAttribute textAttribute) noexcept;
void SetAttributesFromLegacy(const WORD wNew) noexcept;
private:
size_t _cchLength;

View File

@@ -138,7 +138,7 @@ void TextAttributeTests::TestTextAttributeColorGetters()
// verify that calculated foreground/background are the same as the direct
// values when reverse video is not set
VERIFY_IS_FALSE(attr.IsReverseVideo());
VERIFY_IS_FALSE(attr._IsReverseVideo());
VERIFY_ARE_EQUAL(red, attr._GetRgbForeground(view, _defaultFg));
VERIFY_ARE_EQUAL(red, attr.CalculateRgbForeground(view, _defaultFg, _defaultBg));
@@ -148,7 +148,7 @@ void TextAttributeTests::TestTextAttributeColorGetters()
// with reverse video set, calculated foreground/background values should be
// switched while getters stay the same
attr.SetReverseVideo(true);
attr.SetMetaAttributes(COMMON_LVB_REVERSE_VIDEO);
VERIFY_ARE_EQUAL(red, attr._GetRgbForeground(view, _defaultFg));
VERIFY_ARE_EQUAL(green, attr.CalculateRgbForeground(view, _defaultFg, _defaultBg));
@@ -166,7 +166,7 @@ void TextAttributeTests::TestReverseDefaultColors()
// verify that calculated foreground/background are the same as the direct
// values when reverse video is not set
VERIFY_IS_FALSE(attr.IsReverseVideo());
VERIFY_IS_FALSE(attr._IsReverseVideo());
VERIFY_ARE_EQUAL(_defaultFg, attr._GetRgbForeground(view, _defaultFg));
VERIFY_ARE_EQUAL(_defaultFg, attr.CalculateRgbForeground(view, _defaultFg, _defaultBg));
@@ -176,8 +176,8 @@ void TextAttributeTests::TestReverseDefaultColors()
// with reverse video set, calculated foreground/background values should be
// switched while getters stay the same
attr.SetReverseVideo(true);
VERIFY_IS_TRUE(attr.IsReverseVideo());
attr.SetMetaAttributes(COMMON_LVB_REVERSE_VIDEO);
VERIFY_IS_TRUE(attr._IsReverseVideo());
VERIFY_ARE_EQUAL(_defaultFg, attr._GetRgbForeground(view, _defaultFg));
VERIFY_ARE_EQUAL(_defaultBg, attr.CalculateRgbForeground(view, _defaultFg, _defaultBg));
@@ -186,7 +186,7 @@ void TextAttributeTests::TestReverseDefaultColors()
VERIFY_ARE_EQUAL(_defaultFg, attr.CalculateRgbBackground(view, _defaultFg, _defaultBg));
attr.SetForeground(red);
VERIFY_IS_TRUE(attr.IsReverseVideo());
VERIFY_IS_TRUE(attr._IsReverseVideo());
VERIFY_ARE_EQUAL(red, attr._GetRgbForeground(view, _defaultFg));
VERIFY_ARE_EQUAL(_defaultBg, attr.CalculateRgbForeground(view, _defaultFg, _defaultBg));
@@ -195,7 +195,7 @@ void TextAttributeTests::TestReverseDefaultColors()
VERIFY_ARE_EQUAL(red, attr.CalculateRgbBackground(view, _defaultFg, _defaultBg));
attr.Invert();
VERIFY_IS_FALSE(attr.IsReverseVideo());
VERIFY_IS_FALSE(attr._IsReverseVideo());
attr.SetDefaultForeground();
attr.SetBackground(green);

View File

@@ -46,8 +46,9 @@
<!-- Resources -->
<!-- This resw only defines things that are used in this package's AppxManifest,
so it's not in the common resource items. -->
<PRIResource Include="Resources\*\Resources.resw" />
<PRIResource Include="Resources\en-US\Resources.resw" />
<PRIResource Include="Resources\Resources.resw" />
<OCResourceDirectory Include="Resources" />
</ItemGroup>
<!-- This is picked up by CascadiaResources.build.items. -->
@@ -146,4 +147,6 @@
</PropertyGroup>
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.3.191217003-prerelease\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.3.191217003-prerelease\build\native\Microsoft.UI.Xaml.targets'))" />
</Target>
<Import Project="$(SolutionDir)build\rules\CollectWildcardResources.targets" />
</Project>

View File

@@ -783,7 +783,7 @@ namespace TerminalAppLocalTests
VERIFY_IS_FALSE(profile0._guid.has_value());
const auto serialized0Profile = profile0.GenerateStub();
const auto serialized0Profile = profile0.ToJson();
const auto profile1 = Profile::FromJson(serialized0Profile);
VERIFY_IS_FALSE(profile0._guid.has_value());
VERIFY_ARE_EQUAL(profile1._guid.has_value(), profile0._guid.has_value());
@@ -794,7 +794,7 @@ namespace TerminalAppLocalTests
VERIFY_IS_TRUE(settings._profiles.at(0)._guid.has_value());
const auto serialized1Profile = settings._profiles.at(0).GenerateStub();
const auto serialized1Profile = settings._profiles.at(0).ToJson();
const auto profile2 = Profile::FromJson(serialized1Profile);
VERIFY_IS_TRUE(settings._profiles.at(0)._guid.has_value());

View File

@@ -17,7 +17,6 @@ using namespace winrt::TerminalApp;
using namespace WEX::Logging;
using namespace WEX::TestExecution;
using namespace WEX::Common;
using namespace winrt::Windows::ApplicationModel::DataTransfer;
namespace TerminalAppLocalTests
{

View File

@@ -123,27 +123,27 @@
<Import Project="$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.3.191217003-prerelease\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.3.191217003-prerelease\build\native\Microsoft.UI.Xaml.targets')" />
<!-- Use this to auto-find all the dll's that TerminalConnection produces. We
don't roll these up automatically, so we'll need to copy them manually
(below)
The dependencies from TerminalConnection get rolled up in the
GetPackagingOutputs step, when it produces the "appx recipe". This means
they only show up when the build produces an AppX\ folder for either running
or packaging.
It is literally impossible to produce an AppX\ folder using MSBuild without
packaging an appx, and we don't want to do that anyway, so we use these copy
rules instead.
-->
<ItemGroup>
<TerminalConnectionDlls Include="$(_CppWinrtBinRoot)\TerminalConnection\*.dll"/>
</ItemGroup>
<Import Project="$(OpenConsoleDir)\src\common.build.post.props" />
<Target Name="AfterBuild">
<!-- Use this to auto-find all the dll's that TerminalConnection produces. We
don't roll these up automatically, so we'll need to copy them manually
(below)
The dependencies from TerminalConnection get rolled up in the
GetPackagingOutputs step, when it produces the "appx recipe". This means
they only show up when the build produces an AppX\ folder for either running
or packaging.
It is literally impossible to produce an AppX\ folder using MSBuild without
packaging an appx, and we don't want to do that anyway, so we use these copy
rules instead.
-->
<ItemGroup>
<TerminalConnectionDlls Include="$(_CppWinrtBinRoot)\TerminalConnection\*.dll"/>
</ItemGroup>
<!-- Copy the AppxManifest.xml to another file, because when TAEF is
deploying the app, it'll delete the AppxManifest.xml file from this
directory when it tries to clean up after itself. -->

View File

@@ -39,8 +39,6 @@ Author(s):
#include "../../types/inc/utils.hpp"
#include "../../inc/DefaultSettings.h"
#include <winrt/Windows.ApplicationModel.Resources.Core.h>
#include "winrt/Windows.UI.Xaml.Markup.h"
#include <winrt/Windows.system.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>

View File

@@ -29,6 +29,7 @@ LRESULT CALLBACK HwndTerminal::HwndTerminalWndProc(
UINT uMsg,
WPARAM wParam,
LPARAM lParam) noexcept
try
{
#pragma warning(suppress : 26490) // Win32 APIs can only store void*, have to use reinterpret_cast
HwndTerminal* terminal = reinterpret_cast<HwndTerminal*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
@@ -84,6 +85,7 @@ LRESULT CALLBACK HwndTerminal::HwndTerminalWndProc(
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
CATCH_LOG()
static bool RegisterTermClass(HINSTANCE hInstance) noexcept
{
@@ -686,6 +688,7 @@ void __stdcall TerminalKillFocus(void* terminal)
// - rows - Rows of text data to copy
// - fAlsoCopyFormatting - true if the color and formatting should also be copied, false otherwise
HRESULT HwndTerminal::_CopyTextToSystemClipboard(const TextBuffer::TextAndColor& rows, bool const fAlsoCopyFormatting)
try
{
std::wstring finalString;
@@ -714,7 +717,7 @@ HRESULT HwndTerminal::_CopyTextToSystemClipboard(const TextBuffer::TextAndColor&
RETURN_LAST_ERROR_IF(!OpenClipboard(_hwnd.get()));
{ // Clipboard Scope
auto clipboardCloser = wil::scope_exit([]() noexcept {
auto clipboardCloser = wil::scope_exit([]() {
LOG_LAST_ERROR_IF(!CloseClipboard());
});
@@ -742,6 +745,7 @@ HRESULT HwndTerminal::_CopyTextToSystemClipboard(const TextBuffer::TextAndColor&
return S_OK;
}
CATCH_RETURN()
// Routine Description:
// - Copies the given string onto the global system clipboard in the specified format

View File

@@ -2,7 +2,6 @@
// Licensed under the MIT license.
#include "pch.h"
#include "AppLogic.h"
#include "AppCommandlineArgs.h"
#include "ActionArgs.h"
#include <LibraryResources.h>
@@ -141,11 +140,6 @@ int AppCommandlineArgs::_handleExit(const CLI::App& command, const CLI::Error& e
{
_exitMessage = err.str();
}
// We're displaying an error message - we should always exit instead of
// actually starting the Terminal.
_shouldExitEarly = true;
return result;
}
@@ -157,22 +151,6 @@ int AppCommandlineArgs::_handleExit(const CLI::App& command, const CLI::Error& e
// - <none>
void AppCommandlineArgs::_buildParser()
{
auto versionCallback = [this](int64_t /*count*/) {
if (const auto appLogic{ winrt::TerminalApp::implementation::AppLogic::Current() })
{
// Set our message to display the application name and the current version.
_exitMessage = fmt::format("{0}\n{1}",
til::u16u8(appLogic->ApplicationDisplayName()),
til::u16u8(appLogic->ApplicationVersion()));
// Theoretically, we don't need to exit now, since this isn't really
// an error case. However, in practice, it feels weird to have `wt
// -v` open a new tab, and makes enough sense that `wt -v ;
// split-pane` (or whatever) just displays the version and exits.
_shouldExitEarly = true;
}
};
_app.add_flag_function("-v,--version", versionCallback, RS_A(L"CmdVersionDesc"));
_buildNewTabParser();
_buildSplitPaneParser();
_buildFocusTabParser();
@@ -562,19 +540,6 @@ const std::string& AppCommandlineArgs::GetExitMessage()
return _exitMessage;
}
// Method Description:
// - Returns true if we should exit the application before even starting the
// window. We might want to do this if we're displaying an error message or
// the version string, or if we want to open the settings file.
// Arguments:
// - <none>
// Return Value:
// - true iff we should exit the application before even starting the window
bool AppCommandlineArgs::ShouldExitEarly() const noexcept
{
return _shouldExitEarly;
}
// Method Description:
// - Ensure that the first command in our list of actions is a NewTab action.
// This makes sure that if the user passes a commandline like "wt split-pane

View File

@@ -36,7 +36,6 @@ public:
void ValidateStartupCommands();
std::deque<winrt::TerminalApp::ActionAndArgs>& GetStartupActions();
const std::string& GetExitMessage();
bool ShouldExitEarly() const noexcept;
private:
static const std::wregex _commandDelimiterRegex;
@@ -80,7 +79,6 @@ private:
std::deque<winrt::TerminalApp::ActionAndArgs> _startupActions;
std::string _exitMessage;
bool _shouldExitEarly{ false };
winrt::TerminalApp::NewTerminalArgs _getNewTerminalArgs(NewTerminalSubcommand& subcommand);
void _addNewTerminalArgs(NewTerminalSubcommand& subcommand);

View File

@@ -902,24 +902,15 @@ namespace winrt::TerminalApp::implementation
return 0;
}
winrt::hstring AppLogic::ParseCommandlineMessage()
winrt::hstring AppLogic::EarlyExitMessage()
{
if (_root)
{
return _root->ParseCommandlineMessage();
return _root->EarlyExitMessage();
}
return { L"" };
}
bool AppLogic::ShouldExitEarly()
{
if (_root)
{
return _root->ShouldExitEarly();
}
return false;
}
winrt::hstring AppLogic::ApplicationDisplayName() const
{
try

View File

@@ -28,8 +28,7 @@ namespace winrt::TerminalApp::implementation
[[nodiscard]] std::shared_ptr<::TerminalApp::CascadiaSettings> GetSettings() const noexcept;
int32_t SetStartupCommandline(array_view<const winrt::hstring> actions);
winrt::hstring ParseCommandlineMessage();
bool ShouldExitEarly();
winrt::hstring EarlyExitMessage();
winrt::hstring ApplicationDisplayName() const;
winrt::hstring ApplicationVersion() const;

View File

@@ -13,8 +13,7 @@ namespace TerminalApp
MaximizedMode,
};
[default_interface] runtimeclass AppLogic : IF7Listener
{
[default_interface] runtimeclass AppLogic: IF7Listener {
AppLogic();
// For your own sanity, it's better to do setup outside the ctor.
@@ -29,8 +28,7 @@ namespace TerminalApp
Boolean IsElevated();
Int32 SetStartupCommandline(String[] commands);
String ParseCommandlineMessage { get; };
Boolean ShouldExitEarly { get; };
String EarlyExitMessage { get; };
void LoadSettings();
Windows.UI.Xaml.UIElement GetRoot();

View File

@@ -1,269 +0,0 @@
#include "pch.h"
#include "ColorHelper.h"
#include <limits>
using namespace winrt::TerminalApp;
// Method Description:
// Determines whether or not a given color is light
// Arguments:
// - color: this color is going to be examined whether it
// is light or not
// Return Value:
// - true of light, false if dark
bool ColorHelper::IsBrightColor(const winrt::Windows::UI::Color& color)
{
// https://www.w3.org/TR/AERT#color-contrast
auto brightness = (color.R * 299 + color.G * 587 + color.B * 114) / 1000.f;
return brightness > 128.f;
}
// Method Description:
// Converts a rgb color to an hsl one
// Arguments:
// - color: the rgb color, which is going to be converted
// Return Value:
// - a hsl color with the following ranges
// - H: [0.f -360.f]
// - L: [0.f - 1.f] (rounded to the third decimal place)
// - S: [0.f - 1.f] (rounded to the third decimal place)
HSL ColorHelper::RgbToHsl(const winrt::Windows::UI::Color& color)
{
// https://www.rapidtables.com/convert/color/rgb-to-hsl.html
auto epsilon = std::numeric_limits<float>::epsilon();
auto r = color.R / 255.f;
auto g = color.G / 255.f;
auto b = color.B / 255.f;
auto max = std::max(r, std::max(g, b));
auto min = std::min(r, std::min(g, b));
auto delta = max - min;
auto h = 0.f;
auto s = 0.f;
auto l = (max + min) / 2;
if (delta < epsilon || max < epsilon) /* delta == 0 || max == 0*/
{
l = std::roundf(l * 1000) / 1000;
return HSL{ h, s, l };
}
s = l > 0.5 ? delta / (2 - max - min) : delta / (max + min);
if (max - r < epsilon) // max == r
{
h = (g - b) / delta + (g < b ? 6 : 0);
}
else if (max - g < epsilon) // max == g
{
h = (b - r) / delta + 2;
}
else if (max - b < epsilon) // max == b
{
h = (r - g) / delta + 4;
}
// three decimal places after the comma ought
// to be enough for everybody - Bill Gates, 1981
float finalH = std::roundf(h * 60);
float finalS = std::roundf(s * 1000) / 1000;
float finalL = std::roundf(l * 1000) / 1000;
return HSL{ finalH, finalS, finalL };
}
// Method Description:
// Converts a hsl color to rgb one
// Arguments:
// - color: the hsl color, which is going to be converted
// Return Value:
// - the rgb color (r,g,b - [0, 255] range)
winrt::Windows::UI::Color ColorHelper::HslToRgb(const HSL& color)
{
auto epsilon = std::numeric_limits<float>::epsilon();
auto h = (color.H - 1.f > epsilon) ? color.H / 360.f : color.H;
auto s = (color.S - 1.f > epsilon) ? color.S / 100.f : color.S;
auto l = (color.L - 1.f > epsilon) ? color.L / 100.f : color.L;
auto r = l;
auto g = l;
auto b = l;
if (s > epsilon)
{
auto q = l < 0.5 ? l * (1 + s) : l + s - l * s;
auto p = 2 * l - q;
r = HueToRgb(p, q, h + 1.f / 3.f);
g = HueToRgb(p, q, h);
b = HueToRgb(p, q, h - 1.f / 3.f);
}
auto finalR = static_cast<uint8_t>(std::roundf(r * 255));
auto finalG = static_cast<uint8_t>(std::roundf(g * 255));
auto finalB = static_cast<uint8_t>(std::roundf(b * 255));
uint8_t finalA = 255; //opaque
return winrt::Windows::UI::ColorHelper::FromArgb(finalA, finalR, finalG, finalB);
}
float ColorHelper::HueToRgb(float p, float q, float t)
{
auto epsilon = std::numeric_limits<float>::epsilon();
if (t < 0)
t += 1;
if (t > 1)
t -= 1;
if (t - (1.f / 6.f) < epsilon)
return p + (q - p) * 6 * t;
if (t - .5f < epsilon)
return q;
if (t - 2.f / 3.f < epsilon)
return p + (q - p) * (2.f / 3.f - t) * 6;
return p;
}
// Method Description:
// Lightens a color by a given amount
// Arguments:
// - color: the color which is going to be lightened
// - amount: the lighten amount (0-100)
// Return Value:
// - the lightened color in RGB format
winrt::Windows::UI::Color ColorHelper::Lighten(const winrt::Windows::UI::Color& color, float amount /* = 10.f*/)
{
auto hsl = RgbToHsl(color);
hsl.L += amount / 100;
hsl.L = std::clamp(hsl.L, 0.f, 1.f);
return HslToRgb(hsl);
}
// Method Description:
// Darkens a color by a given amount
// Arguments:
// - color: the color which is going to be darkened
// - amount: the darken amount (0-100)
// Return Value:
// - the darkened color in RGB format
winrt::Windows::UI::Color ColorHelper::Darken(const winrt::Windows::UI::Color& color, float amount /* = 10.f*/)
{
auto hsl = RgbToHsl(color);
hsl.L -= amount / 100;
hsl.L = std::clamp(hsl.L, 0.f, 1.f);
return HslToRgb(hsl);
}
// Method Description:
// Gets an accent color to a given color. Basically, generates
// 16 shades of the color and finds the first which has a good
// contrast according to https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef (WCAG Version 2)
// Readability ratio of 3.5 seems to look quite nicely
// Arguments:
// - color: the color for which we need an accent
// Return Value:
// - the accent color in RGB format
winrt::Windows::UI::Color ColorHelper::GetAccentColor(const winrt::Windows::UI::Color& color)
{
auto accentColor = RgbToHsl(color);
if (accentColor.S < 0.15)
{
accentColor.S = 0.15f;
}
constexpr auto shadeCount = 16;
constexpr auto shadeStep = 1.f / shadeCount;
auto shades = std::map<float, HSL>();
for (auto i = 0; i < 15; i++)
{
auto shade = HSL{ accentColor.H, accentColor.S, i * shadeStep };
auto contrast = GetReadability(shade, accentColor);
shades.insert(std::make_pair(contrast, shade));
}
// 3f is quite nice if the whole non-client area is painted
constexpr auto readability = 1.75f;
for (auto shade : shades)
{
if (shade.first >= readability)
{
return HslToRgb(shade.second);
}
}
return HslToRgb(shades.end()->second);
}
// Method Description:
// Gets the readability of two colors according to
// https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef (WCAG Version 2)
// Arguments:
// - firstColor: the first color for the readability check (hsl)
// - secondColor: the second color for the readability check (hsl)
// Return Value:
// - the readability of the colors according to (WCAG Version 2)
float ColorHelper::GetReadability(const HSL& first, const HSL& second)
{
return GetReadability(HslToRgb(first), HslToRgb(second));
}
// Method Description:
// Gets the readability of two colors according to
// https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef (WCAG Version 2)
// Arguments:
// - firstColor: the first color for the readability check (rgb)
// - secondColor: the second color for the readability check (rgb)
// Return Value:
// - the readability of the colors according to (WCAG Version 2)
float ColorHelper::GetReadability(const winrt::Windows::UI::Color& first, const winrt::Windows::UI::Color& second)
{
auto l1 = GetLuminance(first);
auto l2 = GetLuminance(second);
return (std::max(l1, l2) + 0.05f) / std::min(l1, l2) + 0.05f;
}
// Method Description:
// Calculates the luminance of a given color according to
// https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
// Arguments:
// - color: its luminance is going to be calculated
// Return Value:
// - the luminance of the color
float ColorHelper::GetLuminance(const winrt::Windows::UI::Color& color)
{
auto epsilon = std::numeric_limits<float>::epsilon();
float R, G, B;
auto RsRGB = color.R / 255.f;
auto GsRGB = color.G / 255.f;
auto BsRGB = color.B / 255.f;
if (RsRGB - 0.03928f <= epsilon)
{
R = RsRGB / 12.92f;
}
else
{
R = std::pow(((RsRGB + 0.055f) / 1.055f), 2.4f);
}
if (GsRGB - 0.03928f <= epsilon)
{
G = GsRGB / 12.92f;
}
else
{
G = std::pow(((GsRGB + 0.055f) / 1.055f), 2.4f);
}
if (BsRGB - 0.03928f <= epsilon)
{
B = BsRGB / 12.92f;
}
else
{
B = std::pow(((BsRGB + 0.055f) / 1.055f), 2.4f);
}
float luminance = (0.2126f * R) + (0.7152f * G) + (0.0722f * B);
return std::roundf(luminance * 10000) / 10000.f;
}

View File

@@ -1,32 +0,0 @@
#pragma once
#include "pch.h"
#include <winrt/windows.ui.core.h>
namespace winrt::TerminalApp
{
class HSL
{
public:
float H;
float S;
float L;
};
class ColorHelper
{
public:
static bool IsBrightColor(const Windows::UI::Color& color);
static HSL RgbToHsl(const Windows::UI::Color& color);
static Windows::UI::Color HslToRgb(const HSL& color);
static Windows::UI::Color Lighten(const Windows::UI::Color& color, float amount = 10.f);
static Windows::UI::Color Darken(const Windows::UI::Color& color, float amount = 10.f);
static Windows::UI::Color GetAccentColor(const Windows::UI::Color& color);
static float GetLuminance(const Windows::UI::Color& color);
static float GetReadability(const Windows::UI::Color& first, const Windows::UI::Color& second);
static float GetReadability(const HSL& first, const HSL& second);
private:
static float HueToRgb(float p, float q, float t);
};
}

View File

@@ -1,103 +0,0 @@
#include "pch.h"
#include "ColorPickupFlyout.h"
#include "ColorPickupFlyout.g.cpp"
#include "winrt/Windows.UI.Xaml.Media.h"
#include "winrt/Windows.UI.Xaml.Shapes.h"
#include "winrt/Windows.UI.Xaml.Interop.h"
#include <LibraryResources.h>
namespace winrt::TerminalApp::implementation
{
// Method Description:
// - Default constructor, localizes the buttons and hooks
// up the event fired by the custom color picker, so that
// the tab color is set on the fly when selecting a non-preset color
// Arguments:
// - <none>
ColorPickupFlyout::ColorPickupFlyout()
{
InitializeComponent();
OkButton().Content(winrt::box_value(RS_(L"Ok")));
CustomColorButton().Content(winrt::box_value(RS_(L"TabColorCustomButton/Content")));
ClearColorButton().Content(winrt::box_value(RS_(L"TabColorClearButton/Content")));
}
// Method Description:
// - Handler of the click event for the preset color swatches.
// Reads the color from the clicked rectangle and fires an event
// with the selected color. After that hides the flyout
// Arguments:
// - sender: the rectangle that got clicked
// Return Value:
// - <none>
void ColorPickupFlyout::ColorButton_Click(IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const&)
{
auto button{ sender.as<Windows::UI::Xaml::Controls::Button>() };
auto rectangle{ button.Content().as<Windows::UI::Xaml::Shapes::Rectangle>() };
auto rectClr{ rectangle.Fill().as<Windows::UI::Xaml::Media::SolidColorBrush>() };
_ColorSelectedHandlers(rectClr.Color());
Hide();
}
// Method Description:
// - Handler of the clear color button. Clears the current
// color of the tab, if any. Hides the flyout after that
// Arguments:
// - <none>
// Return Value:
// - <none>
void ColorPickupFlyout::ClearColorButton_Click(IInspectable const&, Windows::UI::Xaml::RoutedEventArgs const&)
{
_ColorClearedHandlers();
Hide();
}
// Method Description:
// - Handler of the select custom color button. Expands or collapses the flyout
// to show the color picker. In order to accomplish this a FlyoutPresenterStyle is used,
// in which a Style is embedded, containing the desired width
// Arguments:
// - <none>
// Return Value:
// - <none>
void ColorPickupFlyout::ShowColorPickerButton_Click(Windows::Foundation::IInspectable const&, Windows::UI::Xaml::RoutedEventArgs const&)
{
auto targetType = this->FlyoutPresenterStyle().TargetType();
auto s = Windows::UI::Xaml::Style{};
s.TargetType(targetType);
auto visibility = customColorPanel().Visibility();
if (visibility == winrt::Windows::UI::Xaml::Visibility::Collapsed)
{
customColorPanel().Visibility(winrt::Windows::UI::Xaml::Visibility::Visible);
auto setter = Windows::UI::Xaml::Setter(Windows::UI::Xaml::FrameworkElement::MinWidthProperty(), winrt::box_value(540));
s.Setters().Append(setter);
}
else
{
customColorPanel().Visibility(winrt::Windows::UI::Xaml::Visibility::Collapsed);
auto setter = Windows::UI::Xaml::Setter(Windows::UI::Xaml::FrameworkElement::MinWidthProperty(), winrt::box_value(0));
s.Setters().Append(setter);
}
this->FlyoutPresenterStyle(s);
}
// Method Description:
// - Handles the color selection of the color pickup. Gets
// the currently selected color and fires an event with it
// Arguments:
// - <none>
// Return Value:
// - <none>
void ColorPickupFlyout::CustomColorButton_Click(Windows::Foundation::IInspectable const&, Windows::UI::Xaml::RoutedEventArgs const&)
{
auto color = customColorPicker().Color();
_ColorSelectedHandlers(color);
Hide();
}
void ColorPickupFlyout::ColorPicker_ColorChanged(const Windows::UI::Xaml::Controls::ColorPicker&, const Windows::UI::Xaml::Controls::ColorChangedEventArgs& args)
{
_ColorSelectedHandlers(args.NewColor());
}
}

View File

@@ -1,27 +0,0 @@
#pragma once
#include "ColorPickupFlyout.g.h"
#include "../cascadia/inc/cppwinrt_utils.h"
namespace winrt::TerminalApp::implementation
{
struct ColorPickupFlyout : ColorPickupFlyoutT<ColorPickupFlyout>
{
ColorPickupFlyout();
void ColorButton_Click(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);
void ShowColorPickerButton_Click(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);
void CustomColorButton_Click(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);
void ClearColorButton_Click(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);
void ColorPicker_ColorChanged(const Windows::UI::Xaml::Controls::ColorPicker&, const Windows::UI::Xaml::Controls::ColorChangedEventArgs& args);
WINRT_CALLBACK(ColorCleared, TerminalApp::ColorClearedArgs);
WINRT_CALLBACK(ColorSelected, TerminalApp::ColorSelectedArgs);
};
}
namespace winrt::TerminalApp::factory_implementation
{
struct ColorPickupFlyout : ColorPickupFlyoutT<ColorPickupFlyout, implementation::ColorPickupFlyout>
{
};
}

View File

@@ -1,12 +0,0 @@
namespace TerminalApp
{
delegate void ColorSelectedArgs(Windows.UI.Color color);
delegate void ColorClearedArgs();
[default_interface] runtimeclass ColorPickupFlyout : Windows.UI.Xaml.Controls.Flyout
{
ColorPickupFlyout();
event ColorSelectedArgs ColorSelected;
event ColorClearedArgs ColorCleared;
}
}

View File

@@ -1,146 +0,0 @@
<Flyout
x:Class="TerminalApp.ColorPickupFlyout"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TerminalApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Flyout.FlyoutPresenterStyle>
<Style TargetType="FlyoutPresenter">
<Setter Property="MinWidth" Value="0"/>
</Style>
</Flyout.FlyoutPresenterStyle>
<StackPanel Orientation="Horizontal">
<StackPanel>
<VariableSizedWrapGrid Orientation="Horizontal" MaximumRowsOrColumns="4" HorizontalAlignment="Center" Margin="0, 3, 0, 0">
<VariableSizedWrapGrid.Resources>
<Style TargetType="Rectangle">
<Setter Property="Width" Value="30"/>
<Setter Property="Height" Value="30"/>
</Style>
<Style TargetType="Button">
<Setter Property="Padding" Value="0"/>
<Setter Property="Margin" Value="2"/>
</Style>
</VariableSizedWrapGrid.Resources>
<Button Click="ColorButton_Click" AutomationProperties.Name="Crimson">
<Button.Content>
<Rectangle Fill="Crimson"/>
</Button.Content>
</Button>
<Button Click="ColorButton_Click" AutomationProperties.Name="SteelBlue">
<Button.Content>
<Rectangle Fill="SteelBlue"/>
</Button.Content>
</Button>
<Button Click="ColorButton_Click" AutomationProperties.Name="MediumSeaGreen">
<Button.Content>
<Rectangle Fill="MediumSeaGreen"/>
</Button.Content>
</Button>
<Button Click="ColorButton_Click" AutomationProperties.Name="DarkOrange">
<Button.Content>
<Rectangle Fill="DarkOrange"/>
</Button.Content>
</Button>
<Button Click="ColorButton_Click" AutomationProperties.Name="MediumVioletRed">
<Button.Content>
<Rectangle Fill="MediumVioletRed"/>
</Button.Content>
</Button>
<Button Click="ColorButton_Click" AutomationProperties.Name="DodgerBlue">
<Button.Content>
<Rectangle Fill="DodgerBlue"/>
</Button.Content>
</Button>
<Button Click="ColorButton_Click" AutomationProperties.Name="LimeGreen">
<Button.Content>
<Rectangle Fill="LimeGreen"/>
</Button.Content>
</Button>
<Button Click="ColorButton_Click" AutomationProperties.Name="Yellow">
<Button.Content>
<Rectangle Fill="Yellow"/>
</Button.Content>
</Button>
<Button Click="ColorButton_Click" AutomationProperties.Name="BlueViolet">
<Button.Content>
<Rectangle Fill="BlueViolet"/>
</Button.Content>
</Button>
<Button Click="ColorButton_Click" AutomationProperties.Name="SlateBlue">
<Button.Content>
<Rectangle Fill="SlateBlue"/>
</Button.Content>
</Button>
<Button Click="ColorButton_Click" AutomationProperties.Name="Lime">
<Button.Content>
<Rectangle Fill="Lime"/>
</Button.Content>
</Button>
<Button Click="ColorButton_Click" AutomationProperties.Name="Tan">
<Button.Content>
<Rectangle Fill="Tan"/>
</Button.Content>
</Button>
<Button Click="ColorButton_Click" AutomationProperties.Name="Magenta">
<Button.Content>
<Rectangle Fill="Magenta"/>
</Button.Content>
</Button>
<Button Click="ColorButton_Click" AutomationProperties.Name="Cyan">
<Button.Content>
<Rectangle Fill="Cyan"/>
</Button.Content>
</Button>
<Button Click="ColorButton_Click" AutomationProperties.Name="SkyBlue">
<Button.Content>
<Rectangle Fill="SkyBlue"/>
</Button.Content>
</Button>
<Button Click="ColorButton_Click" AutomationProperties.Name="DarkGray">
<Button.Content>
<Rectangle Fill="DarkGray"/>
</Button.Content>
</Button>
</VariableSizedWrapGrid>
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
<StackPanel.Resources>
<Style TargetType="Button">
<Setter Property="Margin" Value="2" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
</Style>
</StackPanel.Resources>
<Button Padding="5"
Click="ClearColorButton_Click"
x:Name="ClearColorButton" x:Uid="TabColorClearButton" Content="Reset">
</Button>
<Button Padding="5"
Click="ShowColorPickerButton_Click"
x:Name="CustomColorButton" x:Uid="TabColorCustomButton" Content="Custom...">
</Button>
</StackPanel>
</StackPanel>
<Grid Visibility="Collapsed" x:Name="customColorPanel" Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ColorPicker x:Name="customColorPicker"
IsMoreButtonVisible="True"
IsColorSliderVisible="False"
IsColorChannelTextInputVisible="True"
IsHexInputVisible="True"
IsAlphaEnabled="False"
IsAlphaSliderVisible="False"
IsAlphaTextInputVisible="False"
FontSize="10"
Grid.Row="0"
ColorChanged="ColorPicker_ColorChanged"
>
</ColorPicker>
<Button x:Name="OkButton" Click="CustomColorButton_Click" Grid.Row="1" HorizontalAlignment="Center" MinWidth="130" MinHeight="12" Margin="0, 5, 0, 0" x:Uid="OkButton" Content="**OK**"/>
</Grid>
</StackPanel>
</Flyout>

View File

@@ -47,7 +47,7 @@ ColorScheme::ColorScheme() :
{
}
ColorScheme::ColorScheme(std::wstring name, til::color defaultFg, til::color defaultBg, til::color cursorColor) :
ColorScheme::ColorScheme(std::wstring name, COLORREF defaultFg, COLORREF defaultBg, COLORREF cursorColor) :
_schemeName{ name },
_table{},
_defaultForeground{ defaultFg },
@@ -70,18 +70,44 @@ ColorScheme::~ColorScheme()
// - <none>
void ColorScheme::ApplyScheme(TerminalSettings terminalSettings) const
{
terminalSettings.DefaultForeground(static_cast<COLORREF>(_defaultForeground));
terminalSettings.DefaultBackground(static_cast<COLORREF>(_defaultBackground));
terminalSettings.SelectionBackground(static_cast<COLORREF>(_selectionBackground));
terminalSettings.CursorColor(static_cast<COLORREF>(_cursorColor));
terminalSettings.DefaultForeground(_defaultForeground);
terminalSettings.DefaultBackground(_defaultBackground);
terminalSettings.SelectionBackground(_selectionBackground);
terminalSettings.CursorColor(_cursorColor);
auto const tableCount = gsl::narrow_cast<int>(_table.size());
for (int i = 0; i < tableCount; i++)
{
terminalSettings.SetColorTableEntry(i, static_cast<COLORREF>(_table[i]));
terminalSettings.SetColorTableEntry(i, _table[i]);
}
}
// Method Description:
// - Serialize this object to a JsonObject.
// Arguments:
// - <none>
// Return Value:
// - a JsonObject which is an equivalent serialization of this object.
Json::Value ColorScheme::ToJson() const
{
Json::Value root;
root[JsonKey(NameKey)] = winrt::to_string(_schemeName);
root[JsonKey(ForegroundKey)] = Utils::ColorToHexString(_defaultForeground);
root[JsonKey(BackgroundKey)] = Utils::ColorToHexString(_defaultBackground);
root[JsonKey(SelectionBackgroundKey)] = Utils::ColorToHexString(_selectionBackground);
root[JsonKey(CursorColorKey)] = Utils::ColorToHexString(_cursorColor);
int i = 0;
for (const auto& colorName : TableColors)
{
auto& colorValue = _table.at(i);
root[JsonKey(colorName)] = Utils::ColorToHexString(colorValue);
i++;
}
return root;
}
// Method Description:
// - Create a new instance of this class from a serialized JsonObject.
// Arguments:
@@ -167,27 +193,27 @@ std::wstring_view ColorScheme::GetName() const noexcept
return { _schemeName };
}
std::array<til::color, COLOR_TABLE_SIZE>& ColorScheme::GetTable() noexcept
std::array<COLORREF, COLOR_TABLE_SIZE>& ColorScheme::GetTable() noexcept
{
return _table;
}
til::color ColorScheme::GetForeground() const noexcept
COLORREF ColorScheme::GetForeground() const noexcept
{
return _defaultForeground;
}
til::color ColorScheme::GetBackground() const noexcept
COLORREF ColorScheme::GetBackground() const noexcept
{
return _defaultBackground;
}
til::color ColorScheme::GetSelectionBackground() const noexcept
COLORREF ColorScheme::GetSelectionBackground() const noexcept
{
return _selectionBackground;
}
til::color ColorScheme::GetCursorColor() const noexcept
COLORREF ColorScheme::GetCursorColor() const noexcept
{
return _cursorColor;
}

View File

@@ -35,31 +35,32 @@ class TerminalApp::ColorScheme
{
public:
ColorScheme();
ColorScheme(std::wstring name, til::color defaultFg, til::color defaultBg, til::color cursorColor);
ColorScheme(std::wstring name, COLORREF defaultFg, COLORREF defaultBg, COLORREF cursorColor);
~ColorScheme();
void ApplyScheme(winrt::Microsoft::Terminal::Settings::TerminalSettings terminalSettings) const;
Json::Value ToJson() const;
static ColorScheme FromJson(const Json::Value& json);
bool ShouldBeLayered(const Json::Value& json) const;
void LayerJson(const Json::Value& json);
std::wstring_view GetName() const noexcept;
std::array<til::color, COLOR_TABLE_SIZE>& GetTable() noexcept;
til::color GetForeground() const noexcept;
til::color GetBackground() const noexcept;
til::color GetSelectionBackground() const noexcept;
til::color GetCursorColor() const noexcept;
std::array<COLORREF, COLOR_TABLE_SIZE>& GetTable() noexcept;
COLORREF GetForeground() const noexcept;
COLORREF GetBackground() const noexcept;
COLORREF GetSelectionBackground() const noexcept;
COLORREF GetCursorColor() const noexcept;
static std::optional<std::wstring> GetNameFromJson(const Json::Value& json);
private:
std::wstring _schemeName;
std::array<til::color, COLOR_TABLE_SIZE> _table;
til::color _defaultForeground;
til::color _defaultBackground;
til::color _selectionBackground;
til::color _cursorColor;
std::array<COLORREF, COLOR_TABLE_SIZE> _table;
COLORREF _defaultForeground;
COLORREF _defaultBackground;
COLORREF _selectionBackground;
COLORREF _cursorColor;
friend class TerminalAppLocalTests::SettingsTests;
friend class TerminalAppLocalTests::ColorSchemeTests;

View File

@@ -249,6 +249,40 @@ void GlobalAppSettings::ApplyToSettings(TerminalSettings& settings) const noexce
settings.SoftwareRendering(_softwareRendering);
}
// Method Description:
// - Serialize this object to a JsonObject.
// Arguments:
// - <none>
// Return Value:
// - a JsonObject which is an equivalent serialization of this object.
Json::Value GlobalAppSettings::ToJson() const
{
Json::Value jsonObject;
jsonObject[JsonKey(DefaultProfileKey)] = winrt::to_string(Utils::GuidToString(_defaultProfile));
jsonObject[JsonKey(InitialRowsKey)] = _initialRows;
jsonObject[JsonKey(InitialColsKey)] = _initialCols;
jsonObject[JsonKey(RowsToScrollKey)] = _rowsToScroll;
jsonObject[JsonKey(InitialPositionKey)] = _SerializeInitialPosition(_initialX, _initialY);
jsonObject[JsonKey(AlwaysShowTabsKey)] = _alwaysShowTabs;
jsonObject[JsonKey(ShowTitleInTitlebarKey)] = _showTitleInTitlebar;
jsonObject[JsonKey(ShowTabsInTitlebarKey)] = _showTabsInTitlebar;
jsonObject[JsonKey(WordDelimitersKey)] = winrt::to_string(_wordDelimiters);
jsonObject[JsonKey(CopyOnSelectKey)] = _copyOnSelect;
jsonObject[JsonKey(CopyFormattingKey)] = _copyFormatting;
jsonObject[JsonKey(LaunchModeKey)] = winrt::to_string(_SerializeLaunchMode(_launchMode));
jsonObject[JsonKey(ThemeKey)] = winrt::to_string(_SerializeTheme(_theme));
jsonObject[JsonKey(TabWidthModeKey)] = winrt::to_string(_SerializeTabWidthMode(_tabWidthMode));
jsonObject[JsonKey(KeybindingsKey)] = _keybindings->ToJson();
jsonObject[JsonKey(ConfirmCloseAllKey)] = _confirmCloseAllTabs;
jsonObject[JsonKey(SnapToGridOnResizeKey)] = _SnapToGridOnResize;
jsonObject[JsonKey(ForceFullRepaintRenderingKey)] = _forceFullRepaintRendering;
jsonObject[JsonKey(SoftwareRenderingKey)] = _softwareRendering;
jsonObject[JsonKey(DebugFeaturesKey)] = _debugFeatures;
return jsonObject;
}
// Method Description:
// - Create a new instance of this class from a serialized JsonObject.
// Arguments:

View File

@@ -82,6 +82,7 @@ public:
bool DebugFeaturesEnabled() const noexcept;
Json::Value ToJson() const;
static GlobalAppSettings FromJson(const Json::Value& json);
void LayerJson(const Json::Value& json);

View File

@@ -8,9 +8,9 @@
void TerminalApp::JsonUtils::GetOptionalColor(const Json::Value& json,
std::string_view key,
std::optional<til::color>& target)
std::optional<uint32_t>& target)
{
const auto conversionFn = [](const Json::Value& value) -> til::color {
const auto conversionFn = [](const Json::Value& value) -> uint32_t {
return ::Microsoft::Console::Utils::ColorFromHexString(value.asString());
};
GetOptionalValue(json,

View File

@@ -17,7 +17,7 @@ namespace TerminalApp::JsonUtils
{
void GetOptionalColor(const Json::Value& json,
std::string_view key,
std::optional<til::color>& target);
std::optional<uint32_t>& target);
void GetOptionalString(const Json::Value& json,
std::string_view key,

View File

@@ -4,7 +4,6 @@ the MIT License. See LICENSE in the project root for license information. -->
x:Class="TerminalApp.MinMaxCloseControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TerminalApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
@@ -93,7 +92,21 @@ the MIT License. See LICENSE in the project root for license information. -->
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualStateGroup.Transitions>
<VisualTransition From="PointerOver" To="Normal">
<Storyboard>
<ColorAnimation Storyboard.TargetName="ButtonBaseElement" Storyboard.TargetProperty="(UIElement.Background).(SolidColorBrush.Color)" To="{Binding Color, Source={ThemeResource CaptionButtonBackground}}" Duration="0:0:0.2"/>
<ColorAnimation Storyboard.TargetName="Path" Storyboard.TargetProperty="(UIElement.Stroke).(SolidColorBrush.Color)" To="{Binding Color, Source={ThemeResource CaptionButtonStroke}}" Duration="0:0:0.1"/>
</Storyboard>
</VisualTransition>
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Target="ButtonBaseElement.Background" Value="{ThemeResource CaptionButtonBackground}" />
<Setter Target="Path.Stroke" Value="{ThemeResource CaptionButtonStroke}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOver">
<VisualState.Setters>

View File

@@ -36,7 +36,6 @@ static constexpr std::string_view ConnectionTypeKey{ "connectionType" };
static constexpr std::string_view CommandlineKey{ "commandline" };
static constexpr std::string_view FontFaceKey{ "fontFace" };
static constexpr std::string_view FontSizeKey{ "fontSize" };
static constexpr std::string_view FontWeightKey{ "fontWeight" };
static constexpr std::string_view AcrylicTransparencyKey{ "acrylicOpacity" };
static constexpr std::string_view UseAcrylicKey{ "useAcrylic" };
static constexpr std::string_view ScrollbarStateKey{ "scrollbarState" };
@@ -67,19 +66,6 @@ static constexpr std::wstring_view CursorShapeUnderscore{ L"underscore" };
static constexpr std::wstring_view CursorShapeFilledbox{ L"filledBox" };
static constexpr std::wstring_view CursorShapeEmptybox{ L"emptyBox" };
// Possible values for Font Weight
static constexpr std::string_view FontWeightThin{ "thin" };
static constexpr std::string_view FontWeightExtraLight{ "extra-light" };
static constexpr std::string_view FontWeightLight{ "light" };
static constexpr std::string_view FontWeightSemiLight{ "semi-light" };
static constexpr std::string_view FontWeightNormal{ "normal" };
static constexpr std::string_view FontWeightMedium{ "medium" };
static constexpr std::string_view FontWeightSemiBold{ "semi-bold" };
static constexpr std::string_view FontWeightBold{ "bold" };
static constexpr std::string_view FontWeightExtraBold{ "extra-bold" };
static constexpr std::string_view FontWeightBlack{ "black" };
static constexpr std::string_view FontWeightExtraBlack{ "extra-black" };
// Possible values for Image Stretch Mode
static constexpr std::string_view ImageStretchModeNone{ "none" };
static constexpr std::string_view ImageStretchModeFill{ "fill" };
@@ -129,7 +115,6 @@ Profile::Profile(const std::optional<GUID>& guid) :
_startingDirectory{},
_fontFace{ DEFAULT_FONT_FACE },
_fontSize{ DEFAULT_FONT_SIZE },
/* _fontWeight is initialized below because the structure won't accept a uint16_t directly */
_acrylicTransparency{ 0.5 },
_useAcrylic{ false },
_scrollbarState{},
@@ -143,9 +128,6 @@ Profile::Profile(const std::optional<GUID>& guid) :
_retroTerminalEffect{},
_antialiasingMode{ TextAntialiasingMode::Grayscale }
{
winrt::Windows::UI::Text::FontWeight weight;
weight.Weight = DEFAULT_FONT_WEIGHT;
_fontWeight = weight;
}
Profile::~Profile()
@@ -198,7 +180,6 @@ TerminalSettings Profile::CreateTerminalSettings(const std::unordered_map<std::w
terminalSettings.FontFace(_fontFace);
terminalSettings.FontSize(_fontSize);
terminalSettings.FontWeight(_fontWeight);
terminalSettings.Padding(_padding);
terminalSettings.Commandline(_commandline);
@@ -282,6 +263,183 @@ TerminalSettings Profile::CreateTerminalSettings(const std::unordered_map<std::w
return terminalSettings;
}
// Method Description:
// - Serialize this object to a JsonObject.
// Arguments:
// - <none>
// Return Value:
// - a JsonObject which is an equivalent serialization of this object.
Json::Value Profile::ToJson() const
{
Json::Value root = GenerateStub();
///// Profile-specific settings /////
// As of #2795, all profile-specific settings were moved to GenerateStub. If
// any new profiles-specific settings are added, they should probably be
// added here instead of in that method.
///// Core Settings /////
if (_defaultForeground)
{
root[JsonKey(ForegroundKey)] = Utils::ColorToHexString(_defaultForeground.value());
}
if (_defaultBackground)
{
root[JsonKey(BackgroundKey)] = Utils::ColorToHexString(_defaultBackground.value());
}
if (_selectionBackground)
{
root[JsonKey(SelectionBackgroundKey)] = Utils::ColorToHexString(_selectionBackground.value());
}
if (_cursorColor)
{
root[JsonKey(CursorColorKey)] = Utils::ColorToHexString(_cursorColor.value());
}
if (_schemeName)
{
const auto scheme = winrt::to_string(_schemeName.value());
root[JsonKey(ColorSchemeKey)] = scheme;
}
root[JsonKey(HistorySizeKey)] = _historySize;
root[JsonKey(SnapOnInputKey)] = _snapOnInput;
// Only add the cursor height property if we're a legacy-style cursor.
if (_cursorShape == CursorStyle::Vintage)
{
root[JsonKey(CursorHeightKey)] = _cursorHeight;
}
root[JsonKey(CursorShapeKey)] = winrt::to_string(_SerializeCursorStyle(_cursorShape));
root[JsonKey(CommandlineKey)] = winrt::to_string(_commandline);
root[JsonKey(FontFaceKey)] = winrt::to_string(_fontFace);
root[JsonKey(FontSizeKey)] = _fontSize;
root[JsonKey(AcrylicTransparencyKey)] = _acrylicTransparency;
root[JsonKey(UseAcrylicKey)] = _useAcrylic;
root[JsonKey(PaddingKey)] = winrt::to_string(_padding);
if (_connectionType)
{
root[JsonKey(ConnectionTypeKey)] = winrt::to_string(Utils::GuidToString(_connectionType.value()));
}
if (_scrollbarState)
{
const auto scrollbarState = winrt::to_string(_scrollbarState.value());
root[JsonKey(ScrollbarStateKey)] = scrollbarState;
}
if (_icon)
{
const auto icon = winrt::to_string(_icon.value());
root[JsonKey(IconKey)] = icon;
}
if (_tabTitle)
{
root[JsonKey(TabTitleKey)] = winrt::to_string(_tabTitle.value());
}
if (_suppressApplicationTitle)
{
root[JsonKey(SuppressApplicationTitleKey)] = _suppressApplicationTitle;
}
if (_startingDirectory)
{
root[JsonKey(StartingDirectoryKey)] = winrt::to_string(_startingDirectory.value());
}
if (_backgroundImage)
{
root[JsonKey(BackgroundImageKey)] = winrt::to_string(_backgroundImage.value());
}
if (_backgroundImageOpacity)
{
root[JsonKey(BackgroundImageOpacityKey)] = _backgroundImageOpacity.value();
}
if (_backgroundImageStretchMode)
{
root[JsonKey(BackgroundImageStretchModeKey)] = SerializeImageStretchMode(_backgroundImageStretchMode.value()).data();
}
if (_backgroundImageAlignment)
{
root[JsonKey(BackgroundImageAlignmentKey)] = SerializeImageAlignment(_backgroundImageAlignment.value()).data();
}
root[JsonKey(CloseOnExitKey)] = _SerializeCloseOnExitMode(_closeOnExitMode).data();
if (_retroTerminalEffect)
{
root[JsonKey(RetroTerminalEffectKey)] = _retroTerminalEffect.value();
}
root[JsonKey(AntialiasingModeKey)] = SerializeTextAntialiasingMode(_antialiasingMode).data();
return root;
}
// Method Description:
// - This generates a json object `diff` s.t.
// this = other.LayerJson(diff)
// So if:
// - this has a nullopt for an optional, diff will have null for that member
// - this has a value for an optional, diff will have our value. If the other
// did _not_ have a value, and we did, diff will have our value.
// Arguments:
// - other: the other profile object to use as the "base" for this diff. The
// result could be layered upon that json object to re-create this object's
// serialization.
// Return Value:
// - a diff between this and the other object, such that this could be recreated
// from the diff and the other object.
Json::Value Profile::DiffToJson(const Profile& other) const
{
auto otherJson = other.ToJson();
auto myJson = ToJson();
Json::Value diff;
// Iterate in two steps:
// - first over all the keys in the 'other' object's serialization.
// - then over all the keys in our serialization.
// In this way, we ensure all keys from both objects are present in the
// final object.
for (const auto& key : otherJson.getMemberNames())
{
if (myJson.isMember(key))
{
// Both objects have the key
auto otherVal = otherJson[key];
auto myVal = myJson[key];
if (otherVal != myVal)
{
diff[key] = myVal;
}
}
else
{
// key is not in this json object. Set to null, so that when the
// diff is layered upon the original object, we'll properly set
// nullopt for any optionals that weren't present in this object.
diff[key] = Json::Value::null;
}
}
for (const auto& key : myJson.getMemberNames())
{
if (otherJson.isMember(key))
{
// both objects have this key. Do nothing, this is handled above
}
else
{
// We have a key the other object did not. Add our value.
diff[key] = myJson[key];
}
}
return diff;
}
// Method Description:
// - Generates a Json::Value which is a "stub" of this profile. This stub will
// have enough information that it could be layered with this profile.
@@ -493,12 +651,6 @@ void Profile::LayerJson(const Json::Value& json)
JsonUtils::GetInt(json, FontSizeKey, _fontSize);
if (json.isMember(JsonKey(FontWeightKey)))
{
auto fontWeight{ json[JsonKey(FontWeightKey)] };
_fontWeight = _ParseFontWeight(fontWeight);
}
JsonUtils::GetDouble(json, AcrylicTransparencyKey, _acrylicTransparency);
JsonUtils::GetBool(json, UseAcrylicKey, _useAcrylic);
@@ -576,17 +728,17 @@ void Profile::SetUseAcrylic(bool useAcrylic) noexcept
_useAcrylic = useAcrylic;
}
void Profile::SetDefaultForeground(til::color defaultForeground) noexcept
void Profile::SetDefaultForeground(COLORREF defaultForeground) noexcept
{
_defaultForeground = defaultForeground;
}
void Profile::SetDefaultBackground(til::color defaultBackground) noexcept
void Profile::SetDefaultBackground(COLORREF defaultBackground) noexcept
{
_defaultBackground = defaultBackground;
}
void Profile::SetSelectionBackground(til::color selectionBackground) noexcept
void Profile::SetSelectionBackground(COLORREF selectionBackground) noexcept
{
_selectionBackground = selectionBackground;
}
@@ -765,78 +917,6 @@ std::wstring Profile::EvaluateStartingDirectory(const std::wstring& directory)
}
}
// Method Description:
// - Helper function for converting a user-specified font weight value to its corresponding enum
// Arguments:
// - The value from the settings.json file
// Return Value:
// - The corresponding value which maps to the string provided by the user
winrt::Windows::UI::Text::FontWeight Profile::_ParseFontWeight(const Json::Value& json)
{
if (json.isUInt())
{
winrt::Windows::UI::Text::FontWeight weight;
weight.Weight = static_cast<uint16_t>(json.asUInt());
// We're only accepting variable values between 100 and 990 so we don't go too crazy.
if (weight.Weight >= 100 && weight.Weight <= 990)
{
return weight;
}
}
if (json.isString())
{
auto fontWeight = json.asString();
if (fontWeight == FontWeightThin)
{
return winrt::Windows::UI::Text::FontWeights::Thin();
}
else if (fontWeight == FontWeightExtraLight)
{
return winrt::Windows::UI::Text::FontWeights::ExtraLight();
}
else if (fontWeight == FontWeightLight)
{
return winrt::Windows::UI::Text::FontWeights::Light();
}
else if (fontWeight == FontWeightSemiLight)
{
return winrt::Windows::UI::Text::FontWeights::SemiLight();
}
else if (fontWeight == FontWeightNormal)
{
return winrt::Windows::UI::Text::FontWeights::Normal();
}
else if (fontWeight == FontWeightMedium)
{
return winrt::Windows::UI::Text::FontWeights::Medium();
}
else if (fontWeight == FontWeightSemiBold)
{
return winrt::Windows::UI::Text::FontWeights::SemiBold();
}
else if (fontWeight == FontWeightBold)
{
return winrt::Windows::UI::Text::FontWeights::Bold();
}
else if (fontWeight == FontWeightExtraBold)
{
return winrt::Windows::UI::Text::FontWeights::ExtraBold();
}
else if (fontWeight == FontWeightBlack)
{
return winrt::Windows::UI::Text::FontWeights::Black();
}
else if (fontWeight == FontWeightExtraBlack)
{
return winrt::Windows::UI::Text::FontWeights::ExtraBlack();
}
}
return winrt::Windows::UI::Text::FontWeights::Normal();
}
// Method Description:
// - Helper function for converting a user-specified closeOnExit value to its corresponding enum
// Arguments:

View File

@@ -54,6 +54,8 @@ public:
winrt::Microsoft::Terminal::Settings::TerminalSettings CreateTerminalSettings(const std::unordered_map<std::wstring, ColorScheme>& schemes) const;
Json::Value ToJson() const;
Json::Value DiffToJson(const Profile& other) const;
Json::Value GenerateStub() const;
static Profile FromJson(const Json::Value& json);
bool ShouldBeLayered(const Json::Value& json) const;
@@ -79,9 +81,9 @@ public:
void SetStartingDirectory(std::wstring startingDirectory) noexcept;
void SetName(const std::wstring_view name) noexcept;
void SetUseAcrylic(bool useAcrylic) noexcept;
void SetDefaultForeground(til::color defaultForeground) noexcept;
void SetDefaultBackground(til::color defaultBackground) noexcept;
void SetSelectionBackground(til::color selectionBackground) noexcept;
void SetDefaultForeground(COLORREF defaultForeground) noexcept;
void SetDefaultBackground(COLORREF defaultBackground) noexcept;
void SetSelectionBackground(COLORREF selectionBackground) noexcept;
void SetCloseOnExitMode(CloseOnExitMode mode) noexcept;
void SetConnectionType(GUID connectionType) noexcept;
@@ -114,8 +116,6 @@ private:
static std::tuple<winrt::Windows::UI::Xaml::HorizontalAlignment, winrt::Windows::UI::Xaml::VerticalAlignment> ParseImageAlignment(const std::string_view imageAlignment);
static std::tuple<winrt::Windows::UI::Xaml::HorizontalAlignment, winrt::Windows::UI::Xaml::VerticalAlignment> _ConvertJsonToAlignment(const Json::Value& json);
static winrt::Windows::UI::Text::FontWeight _ParseFontWeight(const Json::Value& json);
static CloseOnExitMode ParseCloseOnExitMode(const Json::Value& json);
static std::string_view _SerializeCloseOnExitMode(const CloseOnExitMode closeOnExitMode);
@@ -139,10 +139,10 @@ private:
// If this is set, then our colors should come from the associated color scheme
std::optional<std::wstring> _schemeName;
std::optional<til::color> _defaultForeground;
std::optional<til::color> _defaultBackground;
std::optional<til::color> _selectionBackground;
std::optional<til::color> _cursorColor;
std::optional<uint32_t> _defaultForeground;
std::optional<uint32_t> _defaultBackground;
std::optional<uint32_t> _selectionBackground;
std::optional<uint32_t> _cursorColor;
std::optional<std::wstring> _tabTitle;
bool _suppressApplicationTitle;
int32_t _historySize;
@@ -154,7 +154,6 @@ private:
std::wstring _fontFace;
std::optional<std::wstring> _startingDirectory;
int32_t _fontSize;
winrt::Windows::UI::Text::FontWeight _fontWeight;
double _acrylicTransparency;
bool _useAcrylic;

View File

@@ -168,27 +168,6 @@
<data name="SettingsMenuItem" xml:space="preserve">
<value>Settings</value>
</data>
<data name="Cancel" xml:space="preserve">
<value>Cancel</value>
</data>
<data name="CloseAll" xml:space="preserve">
<value>Close all</value>
</data>
<data name="CloseWindowWarningTitle" xml:space="preserve">
<value>Do you want to close all tabs?</value>
</data>
<data name="TabClose" xml:space="preserve">
<value>Close</value>
</data>
<data name="TabColorChoose" xml:space="preserve">
<value>Color...</value>
</data>
<data name="TabColorCustomButton.Content" xml:space="preserve">
<value>Custom...</value>
</data>
<data name="TabColorClearButton.Content" xml:space="preserve">
<value>Reset</value>
</data>
<data name="InvalidBackgroundImage" xml:space="preserve">
<value>Found a profile with an invalid "backgroundImage". Defaulting that profile to have no background image. Make sure that when setting a "backgroundImage", the value is a valid file path to an image.</value>
<comment>{Locked="\"backgroundImage\""}</comment>
@@ -253,9 +232,6 @@
<value>Open in the given directory instead of the profile's set "startingDirectory"</value>
<comment>{Locked="\"startingDirectory\""}</comment>
</data>
<data name="CmdVersionDesc" xml:space="preserve">
<value>Display the application version</value>
</data>
<data name="NewTabSplitButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.HelpText" xml:space="preserve">
<value>Press the button to open a new terminal tab with your default profile. Open the flyout to select which profile you want to open.</value>
</data>

View File

@@ -2,12 +2,9 @@
// Licensed under the MIT license.
#include "pch.h"
#include <LibraryResources.h>
#include "ColorPickupFlyout.h"
#include "Tab.h"
#include "Tab.g.cpp"
#include "Utils.h"
#include "ColorHelper.h"
using namespace winrt;
using namespace winrt::Windows::UI::Xaml;
@@ -84,20 +81,6 @@ namespace winrt::TerminalApp::implementation
return _tabViewItem;
}
// Method Description:
// - Called after construction of a Tab object to bind event handlers to its
// associated Pane and TermControl object and to create the context menu of
// the tab item
// Arguments:
// - control: reference to the TermControl object to bind event to
// Return Value:
// - <none>
void Tab::Initialize(const TermControl& control)
{
_BindEventHandlers(control);
_CreateContextMenu();
}
// Method Description:
// - Returns true if this is the currently focused tab. For any set of tabs,
// there should only be one tab that is marked as focused, though each tab has
@@ -150,7 +133,7 @@ namespace winrt::TerminalApp::implementation
// - control: reference to the TermControl object to bind event to
// Return Value:
// - <none>
void Tab::_BindEventHandlers(const TermControl& control) noexcept
void Tab::BindEventHandlers(const TermControl& control) noexcept
{
_AttachEventHandlersToPane(_rootPane);
_AttachEventHandlersToControl(control);
@@ -457,208 +440,6 @@ namespace winrt::TerminalApp::implementation
}
// Method Description:
// - Creates a context menu attached to the tab.
// Currently contains elements allowing to select or
// to close the current tab
// Arguments:
// - <none>
// Return Value:
// - <none>
void Tab::_CreateContextMenu()
{
auto weakThis{ get_weak() };
// Close
Controls::MenuFlyoutItem closeTabMenuItem;
Controls::FontIcon closeSymbol;
closeSymbol.FontFamily(Media::FontFamily{ L"Segoe MDL2 Assets" });
closeSymbol.Glyph(L"\xE8BB");
closeTabMenuItem.Click([weakThis](auto&&, auto&&) {
if (auto tab{ weakThis.get() })
{
tab->_rootPane->Close();
}
});
closeTabMenuItem.Text(RS_(L"TabClose"));
closeTabMenuItem.Icon(closeSymbol);
// "Color..."
Controls::MenuFlyoutItem chooseColorMenuItem;
Controls::FontIcon colorPickSymbol;
colorPickSymbol.FontFamily(Media::FontFamily{ L"Segoe MDL2 Assets" });
colorPickSymbol.Glyph(L"\xE790");
chooseColorMenuItem.Click([weakThis](auto&&, auto&&) {
if (auto tab{ weakThis.get() })
{
tab->_tabColorPickup.ShowAt(tab->_tabViewItem);
}
});
chooseColorMenuItem.Text(RS_(L"TabColorChoose"));
chooseColorMenuItem.Icon(colorPickSymbol);
// Color Picker (it's convenient to have it here)
_tabColorPickup.ColorSelected([weakThis](auto newTabColor) {
if (auto tab{ weakThis.get() })
{
tab->_SetTabColor(newTabColor);
}
});
_tabColorPickup.ColorCleared([weakThis]() {
if (auto tab{ weakThis.get() })
{
tab->_ResetTabColor();
}
});
// Build the menu
Controls::MenuFlyout newTabFlyout;
Controls::MenuFlyoutSeparator menuSeparator;
newTabFlyout.Items().Append(chooseColorMenuItem);
newTabFlyout.Items().Append(menuSeparator);
newTabFlyout.Items().Append(closeTabMenuItem);
_tabViewItem.ContextFlyout(newTabFlyout);
}
// Method Description:
// Returns the tab color, if any
// Arguments:
// - <none>
// Return Value:
// - The tab's color, if any
std::optional<winrt::Windows::UI::Color> Tab::GetTabColor()
{
return _tabColor;
}
// Method Description:
// - Sets the tab background color to the color chosen by the user
// - Sets the tab foreground color depending on the luminance of
// the background color
// Arguments:
// - color: the shiny color the user picked for their tab
// Return Value:
// - <none>
void Tab::_SetTabColor(const winrt::Windows::UI::Color& color)
{
auto weakThis{ get_weak() };
_tabViewItem.Dispatcher().RunAsync(CoreDispatcherPriority::Normal, [weakThis, color]() {
auto ptrTab = weakThis.get();
if (!ptrTab)
return;
auto tab{ ptrTab };
Media::SolidColorBrush selectedTabBrush{};
Media::SolidColorBrush deselectedTabBrush{};
Media::SolidColorBrush fontBrush{};
Media::SolidColorBrush hoverTabBrush{};
// calculate the luminance of the current color and select a font
// color based on that
// see https://www.w3.org/TR/WCAG20/#relativeluminancedef
if (TerminalApp::ColorHelper::IsBrightColor(color))
{
fontBrush.Color(winrt::Windows::UI::Colors::Black());
}
else
{
fontBrush.Color(winrt::Windows::UI::Colors::White());
}
hoverTabBrush.Color(TerminalApp::ColorHelper::GetAccentColor(color));
selectedTabBrush.Color(color);
// currently if a tab has a custom color, a deselected state is
// signified by using the same color with a bit ot transparency
auto deselectedTabColor = color;
deselectedTabColor.A = 64;
deselectedTabBrush.Color(deselectedTabColor);
// currently if a tab has a custom color, a deselected state is
// signified by using the same color with a bit ot transparency
tab->_tabViewItem.Resources().Insert(winrt::box_value(L"TabViewItemHeaderBackgroundSelected"), selectedTabBrush);
tab->_tabViewItem.Resources().Insert(winrt::box_value(L"TabViewItemHeaderBackground"), deselectedTabBrush);
tab->_tabViewItem.Resources().Insert(winrt::box_value(L"TabViewItemHeaderBackgroundPointerOver"), hoverTabBrush);
tab->_tabViewItem.Resources().Insert(winrt::box_value(L"TabViewItemHeaderBackgroundPressed"), selectedTabBrush);
tab->_tabViewItem.Resources().Insert(winrt::box_value(L"TabViewItemHeaderForeground"), fontBrush);
tab->_tabViewItem.Resources().Insert(winrt::box_value(L"TabViewItemHeaderForegroundSelected"), fontBrush);
tab->_tabViewItem.Resources().Insert(winrt::box_value(L"TabViewItemHeaderForegroundPointerOver"), fontBrush);
tab->_tabViewItem.Resources().Insert(winrt::box_value(L"TabViewItemHeaderForegroundPressed"), fontBrush);
tab->_RefreshVisualState();
tab->_tabColor.emplace(color);
tab->_colorSelected(color);
});
}
// Method Description:
// Clear the custom color of the tab, if any
// the background color
// Arguments:
// - <none>
// Return Value:
// - <none>
void Tab::_ResetTabColor()
{
auto weakThis{ get_weak() };
_tabViewItem.Dispatcher().RunAsync(CoreDispatcherPriority::Normal, [weakThis]() {
auto ptrTab = weakThis.get();
if (!ptrTab)
return;
auto tab{ ptrTab };
winrt::hstring keys[] = {
L"TabViewItemHeaderBackground",
L"TabViewItemHeaderBackgroundSelected",
L"TabViewItemHeaderBackgroundPointerOver",
L"TabViewItemHeaderForeground",
L"TabViewItemHeaderForegroundSelected",
L"TabViewItemHeaderForegroundPointerOver",
L"TabViewItemHeaderBackgroundPressed",
L"TabViewItemHeaderForegroundPressed"
};
// simply clear any of the colors in the tab's dict
for (auto keyString : keys)
{
auto key = winrt::box_value(keyString);
if (tab->_tabViewItem.Resources().HasKey(key))
{
tab->_tabViewItem.Resources().Remove(key);
}
}
tab->_RefreshVisualState();
tab->_tabColor.reset();
tab->_colorCleared();
});
}
// Method Description:
// Toggles the visual state of the tab view item,
// so that changes to the tab color are reflected immediately
// Arguments:
// - <none>
// Return Value:
// - <none>
void Tab::_RefreshVisualState()
{
if (_focused)
{
winrt::Windows::UI::Xaml::VisualStateManager::GoToState(_tabViewItem, L"Normal", true);
winrt::Windows::UI::Xaml::VisualStateManager::GoToState(_tabViewItem, L"Selected", true);
}
else
{
winrt::Windows::UI::Xaml::VisualStateManager::GoToState(_tabViewItem, L"Selected", true);
winrt::Windows::UI::Xaml::VisualStateManager::GoToState(_tabViewItem, L"Normal", true);
}
}
// - Get the total number of leaf panes in this tab. This will be the number
// of actual controls hosted by this tab.
// Arguments:
@@ -686,6 +467,4 @@ namespace winrt::TerminalApp::implementation
}
DEFINE_EVENT(Tab, ActivePaneChanged, _ActivePaneChangedHandlers, winrt::delegate<>);
DEFINE_EVENT(Tab, ColorSelected, _colorSelected, winrt::delegate<winrt::Windows::UI::Color>);
DEFINE_EVENT(Tab, ColorCleared, _colorCleared, winrt::delegate<>);
}

View File

@@ -3,7 +3,6 @@
#pragma once
#include "Pane.h"
#include "ColorPickupFlyout.h"
#include "Tab.g.h"
// fwdecl unittest classes
@@ -20,8 +19,8 @@ namespace winrt::TerminalApp::implementation
Tab() = delete;
Tab(const GUID& profile, const winrt::Microsoft::Terminal::TerminalControl::TermControl& control);
// Called after construction to perform the necessary setup, which relies on weak_ptr
void Initialize(const winrt::Microsoft::Terminal::TerminalControl::TermControl& control);
// Called after construction to setup events with weak_ptr
void BindEventHandlers(const winrt::Microsoft::Terminal::TerminalControl::TermControl& control) noexcept;
winrt::Microsoft::UI::Xaml::Controls::TabViewItem GetTabViewItem();
winrt::Windows::UI::Xaml::UIElement GetRootElement();
@@ -52,13 +51,9 @@ namespace winrt::TerminalApp::implementation
void Shutdown();
void ClosePane();
std::optional<winrt::Windows::UI::Color> GetTabColor();
WINRT_CALLBACK(Closed, winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable>);
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
DECLARE_EVENT(ActivePaneChanged, _ActivePaneChangedHandlers, winrt::delegate<>);
DECLARE_EVENT(ColorSelected, _colorSelected, winrt::delegate<winrt::Windows::UI::Color>);
DECLARE_EVENT(ColorCleared, _colorCleared, winrt::delegate<>);
OBSERVABLE_GETSET_PROPERTY(winrt::hstring, Title, _PropertyChangedHandlers);
OBSERVABLE_GETSET_PROPERTY(winrt::hstring, IconPath, _PropertyChangedHandlers);
@@ -67,8 +62,6 @@ namespace winrt::TerminalApp::implementation
std::shared_ptr<Pane> _rootPane{ nullptr };
std::shared_ptr<Pane> _activePane{ nullptr };
winrt::hstring _lastIconPath{};
winrt::TerminalApp::ColorPickupFlyout _tabColorPickup{};
std::optional<winrt::Windows::UI::Color> _tabColor{};
bool _focused{ false };
winrt::Microsoft::UI::Xaml::Controls::TabViewItem _tabViewItem{ nullptr };
@@ -76,13 +69,6 @@ namespace winrt::TerminalApp::implementation
void _MakeTabViewItem();
void _Focus();
void _CreateContextMenu();
void _SetTabColor(const winrt::Windows::UI::Color& color);
void _ResetTabColor();
void _RefreshVisualState();
void _BindEventHandlers(const winrt::Microsoft::Terminal::TerminalControl::TermControl& control) noexcept;
void _AttachEventHandlersToControl(const winrt::Microsoft::Terminal::TerminalControl::TermControl& control);
void _AttachEventHandlersToPane(std::shared_ptr<Pane> pane);

View File

@@ -68,7 +68,6 @@
somehow. So make sure to only include top-level dependencies here (don't
include Settings and Connection, since Control will include them for us) -->
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalSettings\TerminalSettings.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalSettingsControl\TerminalSettingsControl.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalConnection\TerminalConnection.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalControl\TerminalControl.vcxproj" />
<!-- Reference TerminalAppLib here, so we can use it's TerminalApp.winmd as

View File

@@ -17,11 +17,8 @@
#include "AzureCloudShellGenerator.h" // For AzureConnectionType
#include "TelnetGenerator.h" // For TelnetConnectionType
#include "TabRowControl.h"
#include "ColorHelper.h"
#include "DebugTapConnection.h"
#include <winrt/Microsoft.Terminal.Settings.Control.h>
using namespace winrt;
using namespace winrt::Windows::Foundation::Collections;
using namespace winrt::Windows::UI::Xaml;
@@ -922,7 +919,7 @@ namespace winrt::TerminalApp::implementation
term.PasteFromClipboard({ this, &TerminalPage::_PasteFromClipboardHandler });
// Bind Tab events to the TermControl and the Tab's Pane
hostingTab.Initialize(term);
hostingTab.BindEventHandlers(term);
// Don't capture a strong ref to the tab. If the tab is removed as this
// is called, we don't really care anymore about handling the event.
@@ -938,34 +935,6 @@ namespace winrt::TerminalApp::implementation
page->_UpdateTitle(*tab);
}
});
// react on color changed events
hostingTab.ColorSelected([weakTab{ hostingTab.get_weak() }, weakThis{ get_weak() }](auto&& color) {
auto page{ weakThis.get() };
auto tab{ weakTab.get() };
if (page && tab && tab->IsFocused())
{
page->_SetNonClientAreaColors(color);
}
});
hostingTab.ColorCleared([weakTab{ hostingTab.get_weak() }, weakThis{ get_weak() }]() {
auto page{ weakThis.get() };
auto tab{ weakTab.get() };
if (page && tab && tab->IsFocused())
{
page->_ClearNonClientAreaColors();
}
});
// TODO GH#3327: Once we support colorizing the NewTab button based on
// the color of the tab, we'll want to make sure to call
// _ClearNewTabButtonColor here, to reset it to the default (for the
// newly created tab).
// remove any colors left by other colored tabs
// _ClearNewTabButtonColor();
}
// Method Description:
@@ -1512,29 +1481,20 @@ namespace winrt::TerminalApp::implementation
// a background thread, as to not hang/crash the UI thread.
fire_and_forget TerminalPage::_LaunchSettings(const bool openDefaults)
{
openDefaults;
// This will switch the execution of the function to a background (not
// UI) thread. This is IMPORTANT, because the Windows.Storage API's
// (used for retrieving the path to the file) will crash on the UI
// thread, because the main thread is a STA.
co_await winrt::resume_background();
auto settingsPage = winrt::make_self<::winrt::Microsoft::Terminal::Settings::Control::MainPage>();
auto tabViewItem = ::winrt::MUX::Controls::TabViewItem{};
_tabView.TabItems().Append(tabViewItem);
_tabView.SelectedItem(settingsPage);
const auto settingsPath = openDefaults ? CascadiaSettings::GetDefaultSettingsPath() :
CascadiaSettings::GetSettingsPath();
//// This will switch the execution of the function to a background (not
//// UI) thread. This is IMPORTANT, because the Windows.Storage API's
//// (used for retrieving the path to the file) will crash on the UI
//// thread, because the main thread is a STA.
//co_await winrt::resume_background();
//const auto settingsPath = openDefaults ? CascadiaSettings::GetDefaultSettingsPath() :
// CascadiaSettings::GetSettingsPath();
//HINSTANCE res = ShellExecute(nullptr, nullptr, settingsPath.c_str(), nullptr, nullptr, SW_SHOW);
//if (static_cast<int>(reinterpret_cast<uintptr_t>(res)) <= 32)
//{
// ShellExecute(nullptr, nullptr, L"notepad", settingsPath.c_str(), nullptr, SW_SHOW);
//}
HINSTANCE res = ShellExecute(nullptr, nullptr, settingsPath.c_str(), nullptr, nullptr, SW_SHOW);
if (static_cast<int>(reinterpret_cast<uintptr_t>(res)) <= 32)
{
ShellExecute(nullptr, nullptr, L"notepad", settingsPath.c_str(), nullptr, SW_SHOW);
}
}
// Method Description:
@@ -1575,10 +1535,6 @@ namespace winrt::TerminalApp::implementation
_RemoveTabViewItem(sender.as<MUX::Controls::TabViewItem>());
eventArgs.Handled(true);
}
else if (eventArgs.GetCurrentPoint(*this).Properties().IsRightButtonPressed())
{
eventArgs.Handled(true);
}
}
void TerminalPage::_UpdatedSelectedTab(const int32_t index)
@@ -1600,20 +1556,7 @@ namespace winrt::TerminalApp::implementation
_tabContent.Children().Append(tab->GetRootElement());
tab->SetFocused(true);
// Raise an event that our title changed
_titleChangeHandlers(*this, Title());
// Raise an event that our titlebar color changed
std::optional<Windows::UI::Color> color = tab->GetTabColor();
if (color.has_value())
{
_SetNonClientAreaColors(color.value());
}
else
{
_ClearNonClientAreaColors();
}
}
CATCH_LOG();
}
@@ -1857,31 +1800,16 @@ namespace winrt::TerminalApp::implementation
// message. If there were no errors, this message will be blank.
// - If the user requested help on any command (using --help), this will
// contain the help message.
// - If the user requested the version number (using --version), this will
// contain the version string.
// Arguments:
// - <none>
// Return Value:
// - the help text or error message for the provided commandline, if one
// exists, otherwise the empty string.
winrt::hstring TerminalPage::ParseCommandlineMessage()
winrt::hstring TerminalPage::EarlyExitMessage()
{
return winrt::to_hstring(_appArgs.GetExitMessage());
}
// Method Description:
// - Returns true if we should exit the application before even starting the
// window. We might want to do this if we're displaying an error message or
// the version string, or if we want to open the settings file.
// Arguments:
// - <none>
// Return Value:
// - true iff we should exit the application before even starting the window
bool TerminalPage::ShouldExitEarly()
{
return _appArgs.ShouldExitEarly();
}
// Method Description:
// - Returns a com_ptr to the implementation type of the tab at the given index
// Arguments:
@@ -1908,158 +1836,6 @@ namespace winrt::TerminalApp::implementation
return tabImpl;
}
// Method Description:
// - Sets the tab split button color when a new tab color is selected
// Arguments:
// - color: The color of the newly selected tab, used to properly calculate
// the foreground color of the split button (to match the font
// color of the tab)
// - accentColor: the actual color we are going to use to paint the tab row and
// split button, so that there is some contrast between the tab
// and the non-client are behind it
// Return Value:
// - <none>
void TerminalPage::_SetNewTabButtonColor(const Windows::UI::Color& color, const Windows::UI::Color& accentColor)
{
// TODO GH#3327: Look at what to do with the tab button when we have XAML theming
bool IsBrightColor = ColorHelper::IsBrightColor(color);
bool isLightAccentColor = ColorHelper::IsBrightColor(accentColor);
winrt::Windows::UI::Color pressedColor{};
winrt::Windows::UI::Color hoverColor{};
winrt::Windows::UI::Color foregroundColor{};
const float hoverColorAdjustment = 5.f;
const float pressedColorAdjustment = 7.f;
if (IsBrightColor)
{
foregroundColor = winrt::Windows::UI::Colors::Black();
}
else
{
foregroundColor = winrt::Windows::UI::Colors::White();
}
if (isLightAccentColor)
{
hoverColor = ColorHelper::Darken(accentColor, hoverColorAdjustment);
pressedColor = ColorHelper::Darken(accentColor, pressedColorAdjustment);
}
else
{
hoverColor = ColorHelper::Lighten(accentColor, hoverColorAdjustment);
pressedColor = ColorHelper::Lighten(accentColor, pressedColorAdjustment);
}
Media::SolidColorBrush backgroundBrush{ accentColor };
Media::SolidColorBrush backgroundHoverBrush{ hoverColor };
Media::SolidColorBrush backgroundPressedBrush{ pressedColor };
Media::SolidColorBrush foregroundBrush{ foregroundColor };
_newTabButton.Resources().Insert(winrt::box_value(L"SplitButtonBackground"), backgroundBrush);
_newTabButton.Resources().Insert(winrt::box_value(L"SplitButtonBackgroundPointerOver"), backgroundHoverBrush);
_newTabButton.Resources().Insert(winrt::box_value(L"SplitButtonBackgroundPressed"), backgroundPressedBrush);
_newTabButton.Resources().Insert(winrt::box_value(L"SplitButtonForeground"), foregroundBrush);
_newTabButton.Resources().Insert(winrt::box_value(L"SplitButtonForegroundPointerOver"), foregroundBrush);
_newTabButton.Resources().Insert(winrt::box_value(L"SplitButtonForegroundPressed"), foregroundBrush);
_newTabButton.Background(backgroundBrush);
_newTabButton.Foreground(foregroundBrush);
}
// Method Description:
// - Clears the tab split button color to a system color
// (or white if none is found) when the tab's color is cleared
// - Clears the tab row color to a system color
// (or white if none is found) when the tab's color is cleared
// Arguments:
// - <none>
// Return Value:
// - <none>
void TerminalPage::_ClearNewTabButtonColor()
{
// TODO GH#3327: Look at what to do with the tab button when we have XAML theming
winrt::hstring keys[] = {
L"SplitButtonBackground",
L"SplitButtonBackgroundPointerOver",
L"SplitButtonBackgroundPressed",
L"SplitButtonForeground",
L"SplitButtonForegroundPointerOver",
L"SplitButtonForegroundPressed"
};
// simply clear any of the colors in the split button's dict
for (auto keyString : keys)
{
auto key = winrt::box_value(keyString);
if (_newTabButton.Resources().HasKey(key))
{
_newTabButton.Resources().Remove(key);
}
}
const auto res = Application::Current().Resources();
const auto defaultBackgroundKey = winrt::box_value(L"TabViewItemHeaderBackground");
const auto defaultForegroundKey = winrt::box_value(L"SystemControlForegroundBaseHighBrush");
winrt::Windows::UI::Xaml::Media::SolidColorBrush backgroundBrush;
winrt::Windows::UI::Xaml::Media::SolidColorBrush foregroundBrush;
// TODO: Related to GH#3917 - I think if the system is set to "Dark"
// theme, but the app is set to light theme, then this lookup still
// returns to us the dark theme brushes. There's gotta be a way to get
// the right brushes...
// See also GH#5741
if (res.HasKey(defaultBackgroundKey))
{
winrt::Windows::Foundation::IInspectable obj = res.Lookup(defaultBackgroundKey);
backgroundBrush = obj.try_as<winrt::Windows::UI::Xaml::Media::SolidColorBrush>();
}
else
{
backgroundBrush = winrt::Windows::UI::Xaml::Media::SolidColorBrush{ winrt::Windows::UI::Colors::Black() };
}
if (res.HasKey(defaultForegroundKey))
{
winrt::Windows::Foundation::IInspectable obj = res.Lookup(defaultForegroundKey);
foregroundBrush = obj.try_as<winrt::Windows::UI::Xaml::Media::SolidColorBrush>();
}
else
{
foregroundBrush = winrt::Windows::UI::Xaml::Media::SolidColorBrush{ winrt::Windows::UI::Colors::White() };
}
_newTabButton.Background(backgroundBrush);
_newTabButton.Foreground(foregroundBrush);
}
// Method Description:
// - Sets the tab split button color when a new tab color is selected
// - This method could also set the color of the title bar and tab row
// in the future
// Arguments:
// - selectedTabColor: The color of the newly selected tab
// Return Value:
// - <none>
void TerminalPage::_SetNonClientAreaColors(const Windows::UI::Color& /*selectedTabColor*/)
{
// TODO GH#3327: Look at what to do with the NC area when we have XAML theming
}
// Method Description:
// - Clears the tab split button color when the tab's color is cleared
// - This method could also clear the color of the title bar and tab row
// in the future
// Arguments:
// - <none>
// Return Value:
// - <none>
void TerminalPage::_ClearNonClientAreaColors()
{
// TODO GH#3327: Look at what to do with the NC area when we have XAML theming
}
// -------------------------------- WinRT Events ---------------------------------
// Winrt events need a method for adding a callback to the event and removing the callback.
// These macros will define them both for you.

View File

@@ -50,8 +50,7 @@ namespace winrt::TerminalApp::implementation
void CloseWindow();
int32_t SetStartupCommandline(winrt::array_view<const hstring> args);
winrt::hstring ParseCommandlineMessage();
bool ShouldExitEarly();
winrt::hstring EarlyExitMessage();
// -------------------------------- WinRT Events ---------------------------------
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(TitleChanged, _titleChangeHandlers, winrt::Windows::Foundation::IInspectable, winrt::hstring);
@@ -168,11 +167,6 @@ namespace winrt::TerminalApp::implementation
void _ToggleFullscreen();
void _SetNonClientAreaColors(const Windows::UI::Color& selectedTabColor);
void _ClearNonClientAreaColors();
void _SetNewTabButtonColor(const Windows::UI::Color& color, const Windows::UI::Color& accentColor);
void _ClearNewTabButtonColor();
#pragma region ActionHandlers
// These are all defined in AppActionHandlers.cpp
void _HandleOpenNewTabDropdown(const IInspectable& sender, const TerminalApp::ActionEventArgs& args);

View File

@@ -11,8 +11,7 @@ namespace TerminalApp
TerminalPage();
Int32 SetStartupCommandline(String[] commands);
String ParseCommandlineMessage { get; };
Boolean ShouldExitEarly { get; };
String EarlyExitMessage { get; };
// XAML bound properties
String ApplicationDisplayName { get; };

View File

@@ -93,4 +93,5 @@ namespace winrt::TerminalApp::implementation
{
MinMaxCloseControl().SetWindowVisualState(visualState);
}
}

View File

@@ -21,6 +21,7 @@ namespace winrt::TerminalApp::implementation
void Content(IInspectable content);
void SetWindowVisualState(WindowVisualState visualState);
void Root_SizeChanged(const IInspectable& sender, Windows::UI::Xaml::SizeChangedEventArgs const& e);
void Minimize_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);

View File

@@ -29,7 +29,7 @@
{
"guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
"name": "Windows PowerShell",
"commandline": "powershell.exe",
"commandline": "%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
"icon": "ms-appx:///ProfileIcons/{61c54bbd-c2c6-5271-96e7-009a87ff44bf}.png",
"colorScheme": "Campbell",
"antialiasingMode": "grayscale",
@@ -47,7 +47,7 @@
{
"guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
"name": "Command Prompt",
"commandline": "cmd.exe",
"commandline": "%SystemRoot%\\System32\\cmd.exe",
"icon": "ms-appx:///ProfileIcons/{0caa0dad-35be-5f56-a8ff-afceeeaa6101}.png",
"colorScheme": "Campbell",
"antialiasingMode": "grayscale",

View File

@@ -60,9 +60,6 @@
<Page Include="../TabRowControl.xaml">
<SubType>Designer</SubType>
</Page>
<Page Include="../ColorPickupFlyout.xaml">
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<!-- ========================= Headers ======================== -->
<ItemGroup>
@@ -82,9 +79,6 @@
<ClInclude Include="../TabRowControl.h">
<DependentUpon>../TabRowControl.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="../ColorPickupFlyout.h">
<DependentUpon>../ColorPickupFlyout.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="../Tab.h">
<DependentUpon>../Tab.idl</DependentUpon>
</ClInclude>
@@ -103,7 +97,6 @@
<ClInclude Include="../WslDistroGenerator.h" />
<ClInclude Include="../AzureCloudShellGenerator.h" />
<ClInclude Include="../TelnetGenerator.h" />
<ClInclude Include="..\ColorHelper.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="../ShortcutActionDispatch.h">
<DependentUpon>../ShortcutActionDispatch.idl</DependentUpon>
@@ -143,9 +136,6 @@
<ClCompile Include="../TabRowControl.cpp">
<DependentUpon>../TabRowControl.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="../ColorPickupFlyout.cpp">
<DependentUpon>../ColorPickupFlyout.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="../Tab.cpp">
<DependentUpon>../Tab.idl</DependentUpon>
</ClCompile>
@@ -164,7 +154,6 @@
<ClCompile Include="../WslDistroGenerator.cpp" />
<ClCompile Include="../AzureCloudShellGenerator.cpp" />
<ClCompile Include="../Pane.LayoutSizeNode.cpp" />
<ClCompile Include="../ColorHelper.cpp" />
<ClCompile Include="../DebugTapConnection.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
@@ -225,15 +214,12 @@
<DependentUpon>../TabRowControl.xaml</DependentUpon>
<SubType>Code</SubType>
</Midl>
<Midl Include="../ColorPickupFlyout.idl">
<DependentUpon>../ColorPickupFlyout.xaml</DependentUpon>
<SubType>Code</SubType>
</Midl>
<Midl Include="../Tab.idl"/>
</ItemGroup>
<!-- ========================= Misc Files ======================== -->
<ItemGroup>
<PRIResource Include="..\Resources\*\Resources.resw" />
<PRIResource Include="..\Resources\en-US\Resources.resw" />
<OCResourceDirectory Include="../Resources" />
<None Include="../packages.config" />
</ItemGroup>
<!-- ========================= Project References ======================== -->
@@ -274,12 +260,6 @@
<Private>false</Private>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
</Reference>
<Reference Include="Microsoft.Terminal.Settings.Control">
<HintPath>$(_BinRoot)TerminalSettingsControl\Microsoft.Terminal.Settings.Control.winmd</HintPath>
<IsWinMDFile>true</IsWinMDFile>
<Private>false</Private>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
</Reference>
<Reference Include="Microsoft.Terminal.TerminalConnection">
<HintPath>$(_BinRoot)TerminalConnection\Microsoft.Terminal.TerminalConnection.winmd</HintPath>
<IsWinMDFile>true</IsWinMDFile>
@@ -351,4 +331,6 @@
<Target Name="_TerminalAppGenerateUserSettingsH" Inputs="..\userDefaults.json" Outputs="Generated Files\userDefaults.h" BeforeTargets="BeforeClCompile">
<Exec Command="powershell.exe -noprofile ExecutionPolicy Unrestricted $(OpenConsoleDir)\tools\GenerateHeaderForJson.ps1 -JsonFile ..\userDefaults.json -OutPath '&quot;Generated Files\userDefaults.h&quot;' -VariableName UserSettingsJson" />
</Target>
<Import Project="$(SolutionDir)build\rules\CollectWildcardResources.targets" />
</Project>

View File

@@ -59,7 +59,6 @@
<ClCompile Include="../Pane.LayoutSizeNode.cpp">
<Filter>pane</Filter>
</ClCompile>
<ClCompile Include="..\ColorHelper.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="../Utils.h" />
@@ -108,7 +107,6 @@
<Filter>tab</Filter>
</ClInclude>
<ClInclude Include="../TelnetGenerator.h" />
<ClInclude Include="..\ColorHelper.h" />
</ItemGroup>
<ItemGroup>
<Midl Include="../AppLogic.idl">
@@ -143,9 +141,6 @@
<Page Include="../TitlebarControl.xaml">
<Filter>controls</Filter>
</Page>
<Page Include="../ColorPickupFlyout.xaml">
<Filter>controls</Filter>
</Page>
</ItemGroup>
<ItemGroup>
<Filter Include="app">

View File

@@ -63,7 +63,6 @@ TRACELOGGING_DECLARE_PROVIDER(g_hTerminalAppProvider);
#include <shellapi.h>
#include <winrt/Microsoft.Terminal.TerminalConnection.h>
#include <winrt/Windows.UI.Popups.h>
#include <CLI11/CLI11.hpp>

View File

@@ -294,6 +294,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
// Method Description:
// - called when the client application (not necessarily its pty) exits for any reason
void ConptyConnection::_ClientTerminated() noexcept
try
{
if (_isStateAtOrBeyond(ConnectionState::Closing))
{
@@ -321,6 +322,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
_piClient.reset();
}
CATCH_LOG()
void ConptyConnection::WriteInput(hstring const& data)
{
@@ -349,6 +351,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
}
void ConptyConnection::Close() noexcept
try
{
if (_transitionToState(ConnectionState::Closing))
{
@@ -378,6 +381,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
_transitionToState(ConnectionState::Closed);
}
}
CATCH_LOG()
DWORD ConptyConnection::_OutputThread()
{

View File

@@ -59,7 +59,8 @@
<Midl Include="TelnetConnection.idl" />
</ItemGroup>
<ItemGroup>
<PRIResource Include="Resources\*\Resources.resw" />
<PRIResource Include="Resources\en-US\Resources.resw" />
<OCResourceDirectory Include="Resources" />
<None Include="packages.config" />
</ItemGroup>
<!-- ========================= Project References ======================== -->
@@ -95,4 +96,6 @@
</Link>
</ItemDefinitionGroup>
<Import Project="..\..\..\packages\vcpkg-telnetpp.1.0.1\build\native\vcpkg-telnetpp.targets" Condition="Exists('..\..\..\packages\vcpkg-telnetpp.1.0.1\build\native\vcpkg-telnetpp.targets')" />
<Import Project="$(SolutionDir)build\rules\CollectWildcardResources.targets" />
</Project>

View File

@@ -201,7 +201,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
// things in DIPs, and the fontSize is in pixels.
TextBlock().FontSize(unscaledFontSizePx);
TextBlock().FontFamily(Media::FontFamily(fontArgs->FontFace()));
TextBlock().FontWeight(fontArgs->FontWeight());
// TextBlock's actual dimensions right after initialization is 0w x 0h. So,
// if an IME is displayed before TextBlock has text (like showing the emoji picker

View File

@@ -27,8 +27,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
GETSET_PROPERTY(Windows::Foundation::Size, FontSize);
GETSET_PROPERTY(winrt::hstring, FontFace);
GETSET_PROPERTY(Windows::UI::Text::FontWeight, FontWeight);
};
struct TSFInputControl : TSFInputControlT<TSFInputControl>

View File

@@ -14,7 +14,6 @@ namespace Microsoft.Terminal.TerminalControl
{
String FontFace { get; set; };
Windows.Foundation.Size FontSize { get; set; };
Windows.UI.Text.FontWeight FontWeight { get; set; };
}
[default_interface]

View File

@@ -27,6 +27,10 @@ using namespace winrt::Windows::System;
using namespace winrt::Microsoft::Terminal::Settings;
using namespace winrt::Windows::ApplicationModel::DataTransfer;
// The minimum delay between updates to the scroll bar's values.
// The updates are throttled to limit power usage.
constexpr const auto ScrollBarUpdateInterval = std::chrono::milliseconds(8);
namespace winrt::Microsoft::Terminal::TerminalControl::implementation
{
// Helper static function to ensure that all ambiguous-width glyphs are reported as narrow.
@@ -58,13 +62,13 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
_initializedTerminal{ false },
_settings{ settings },
_closing{ false },
_isTerminalInitiatedScroll{ false },
_isInternalScrollBarUpdate{ false },
_autoScrollVelocity{ 0 },
_autoScrollingPointerPoint{ std::nullopt },
_autoScrollTimer{},
_lastAutoScrollUpdateTime{ std::nullopt },
_desiredFont{ DEFAULT_FONT_FACE, 0, DEFAULT_FONT_WEIGHT, { 0, DEFAULT_FONT_SIZE }, CP_UTF8 },
_actualFont{ DEFAULT_FONT_FACE, 0, DEFAULT_FONT_WEIGHT, { 0, DEFAULT_FONT_SIZE }, CP_UTF8, false },
_desiredFont{ DEFAULT_FONT_FACE, 0, 10, { 0, DEFAULT_FONT_SIZE }, CP_UTF8 },
_actualFont{ DEFAULT_FONT_FACE, 0, 10, { 0, DEFAULT_FONT_SIZE }, CP_UTF8, false },
_touchAnchor{ std::nullopt },
_cursorTimer{},
_lastMouseClickTimestamp{},
@@ -118,6 +122,32 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
}
});
_updateScrollBar = std::make_shared<ThrottledFunc<ScrollBarUpdate>>(
[weakThis = get_weak()](const auto& update) {
if (auto control{ weakThis.get() })
{
control->Dispatcher()
.RunAsync(CoreDispatcherPriority::Normal, [=]() {
if (auto control2{ weakThis.get() })
{
control2->_isInternalScrollBarUpdate = true;
auto scrollBar = control2->ScrollBar();
if (update.newValue.has_value())
{
scrollBar.Value(update.newValue.value());
}
scrollBar.Maximum(update.newMaximum);
scrollBar.Minimum(update.newMinimum);
scrollBar.ViewportSize(update.newViewportSize);
control2->_isInternalScrollBarUpdate = false;
}
});
}
},
ScrollBarUpdateInterval);
static constexpr auto AutoScrollUpdateInterval = std::chrono::microseconds(static_cast<int>(1.0 / 30.0 * 1000000));
_autoScrollTimer.Interval(AutoScrollUpdateInterval);
_autoScrollTimer.Tick({ this, &TermControl::_UpdateAutoScroll });
@@ -212,7 +242,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
{
if (_closing)
{
return;
co_return;
}
// Update our control settings
@@ -253,7 +283,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
{
_InitializeBackgroundBrush();
COLORREF bg = _settings.DefaultBackground();
uint32_t bg = _settings.DefaultBackground();
_BackgroundColorChanged(bg);
// Apply padding as swapChainPanel's margin
@@ -263,19 +293,18 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
// Initialize our font information.
const auto fontFace = _settings.FontFace();
const short fontHeight = gsl::narrow_cast<short>(_settings.FontSize());
const auto fontWeight = _settings.FontWeight();
// The font width doesn't terribly matter, we'll only be using the
// height to look it up
// The other params here also largely don't matter.
// The family is only used to determine if the font is truetype or
// not, but DX doesn't use that info at all.
// The Codepage is additionally not actually used by the DX engine at all.
_actualFont = { fontFace, 0, fontWeight.Weight, { 0, fontHeight }, CP_UTF8, false };
_actualFont = { fontFace, 0, 10, { 0, fontHeight }, CP_UTF8, false };
_desiredFont = { _actualFont };
// set TSF Foreground
Media::SolidColorBrush foregroundBrush{};
foregroundBrush.Color(static_cast<til::color>(_settings.DefaultForeground()));
foregroundBrush.Color(ColorRefToColor(_settings.DefaultForeground()));
TSFInputControl().Foreground(foregroundBrush);
TSFInputControl().Margin(newMargin);
@@ -406,29 +435,37 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
// - color: The background color to use as a uint32 (aka DWORD COLORREF)
// Return Value:
// - <none>
winrt::fire_and_forget TermControl::_BackgroundColorChanged(const COLORREF color)
winrt::fire_and_forget TermControl::_BackgroundColorChanged(const uint32_t color)
{
til::color newBgColor{ color };
auto weakThis{ get_weak() };
co_await winrt::resume_foreground(Dispatcher());
if (auto control{ weakThis.get() })
{
const auto R = GetRValue(color);
const auto G = GetGValue(color);
const auto B = GetBValue(color);
winrt::Windows::UI::Color bgColor{};
bgColor.R = R;
bgColor.G = G;
bgColor.B = B;
bgColor.A = 255;
if (auto acrylic = RootGrid().Background().try_as<Media::AcrylicBrush>())
{
acrylic.FallbackColor(newBgColor);
acrylic.TintColor(newBgColor);
acrylic.FallbackColor(bgColor);
acrylic.TintColor(bgColor);
}
else if (auto solidColor = RootGrid().Background().try_as<Media::SolidColorBrush>())
{
solidColor.Color(newBgColor);
solidColor.Color(bgColor);
}
// Set the default background as transparent to prevent the
// DX layer from overwriting the background image or acrylic effect
_settings.DefaultBackground(static_cast<COLORREF>(newBgColor.with_alpha(0)));
_settings.DefaultBackground(ARGB(0, R, G, B));
}
}
@@ -1302,7 +1339,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
{
_settings.UseAcrylic(false);
_InitializeBackgroundBrush();
COLORREF bg = _settings.DefaultBackground();
uint32_t bg = _settings.DefaultBackground();
_BackgroundColorChanged(bg);
}
else
@@ -1395,8 +1432,11 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
void TermControl::_ScrollbarChangeHandler(Windows::Foundation::IInspectable const& /*sender*/,
Controls::Primitives::RangeBaseValueChangedEventArgs const& args)
{
if (_isTerminalInitiatedScroll || _closing)
if (_isInternalScrollBarUpdate || _closing)
{
// The update comes from ourselves, more specifically from the
// terminal. So we don't have to update the terminal because it
// already knows.
return;
}
@@ -1406,9 +1446,11 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
// itself - it was initiated by the mouse wheel, or the scrollbar.
_terminal->UserScrollViewport(newValue);
// We've just told the terminal to update its viewport to reflect the
// new scroll value so the scroll bar matches the viewport now.
_willUpdateScrollBarToMatchViewport.store(false);
// User input takes priority over terminal events so cancel
// any pending scroll bar update if the user scrolls.
_updateScrollBar->ModifyPending([](auto& update) {
update.newValue.reset();
});
}
// Method Description:
@@ -1679,8 +1721,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
// Make sure we have a non-zero font size
const auto newSize = std::max<short>(gsl::narrow_cast<short>(fontSize), 1);
const auto fontFace = _settings.FontFace();
const auto fontWeight = _settings.FontWeight();
_actualFont = { fontFace, 0, fontWeight.Weight, { 0, newSize }, CP_UTF8, false };
_actualFont = { fontFace, 0, 10, { 0, newSize }, CP_UTF8, false };
_desiredFont = { _actualFont };
auto lock = _terminal->LockForWriting();
@@ -1907,35 +1948,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
_titleChangedHandlers(winrt::hstring{ wstr });
}
// Method Description:
// - Update the position and size of the scrollbar to match the given
// viewport top, viewport height, and buffer size.
// The change will be actually handled in _ScrollbarChangeHandler.
// This should be done on the UI thread. Make sure the caller is calling
// us in a RunAsync block.
// Arguments:
// - viewTop: the top of the visible viewport, in rows. 0 indicates the top
// of the buffer.
// - viewHeight: the height of the viewport in rows.
// - bufferSize: the length of the buffer, in rows
void TermControl::_ScrollbarUpdater(Controls::Primitives::ScrollBar scrollBar,
const int viewTop,
const int viewHeight,
const int bufferSize)
{
// The terminal is already in the scroll position it wants, so no need
// to tell it to scroll.
_isTerminalInitiatedScroll = true;
const auto hiddenContent = bufferSize - viewHeight;
scrollBar.Maximum(hiddenContent);
scrollBar.Minimum(0);
scrollBar.ViewportSize(viewHeight);
scrollBar.Value(viewTop);
_isTerminalInitiatedScroll = false;
}
// Method Description:
// - Update the position and size of the scrollbar to match the given
// viewport top, viewport height, and buffer size.
@@ -1946,9 +1958,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
// of the buffer.
// - viewHeight: the height of the viewport in rows.
// - bufferSize: the length of the buffer, in rows
winrt::fire_and_forget TermControl::_TerminalScrollPositionChanged(const int viewTop,
const int viewHeight,
const int bufferSize)
void TermControl::_TerminalScrollPositionChanged(const int viewTop,
const int viewHeight,
const int bufferSize)
{
// Since this callback fires from non-UI thread, we might be already
// closed/closing.
@@ -1959,21 +1971,14 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
_scrollPositionChangedHandlers(viewTop, viewHeight, bufferSize);
auto weakThis{ get_weak() };
ScrollBarUpdate update;
const auto hiddenContent = bufferSize - viewHeight;
update.newMaximum = hiddenContent;
update.newMinimum = 0;
update.newViewportSize = viewHeight;
update.newValue = viewTop;
co_await winrt::resume_foreground(Dispatcher());
// Even if we weren't closed/closing few lines above, we might be
// while waiting for this block of code to be dispatched.
// If 'weakThis' is locked, then we can safely work with 'this'
if (auto control{ weakThis.get() })
{
if (!_closing.load())
{
// Update our scrollbar
_ScrollbarUpdater(ScrollBar(), viewTop, viewHeight, bufferSize);
}
}
_updateScrollBar->Run(update);
}
// Method Description:
@@ -2199,14 +2204,13 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
// Initialize our font information.
const auto fontFace = settings.FontFace();
const short fontHeight = gsl::narrow_cast<short>(settings.FontSize());
const auto fontWeight = settings.FontWeight();
// The font width doesn't terribly matter, we'll only be using the
// height to look it up
// The other params here also largely don't matter.
// The family is only used to determine if the font is truetype or
// not, but DX doesn't use that info at all.
// The Codepage is additionally not actually used by the DX engine at all.
FontInfo actualFont = { fontFace, 0, fontWeight.Weight, { 0, fontHeight }, CP_UTF8, false };
FontInfo actualFont = { fontFace, 0, 10, { 0, fontHeight }, CP_UTF8, false };
FontInfoDesired desiredFont = { actualFont };
// If the settings have negative or zero row or column counts, ignore those counts.
@@ -2500,9 +2504,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
{
eventArgs.FontSize(CharacterDimensions());
eventArgs.FontFace(_actualFont.GetFaceName());
::winrt::Windows::UI::Text::FontWeight weight;
weight.Weight = static_cast<uint16_t>(_actualFont.GetWeight());
eventArgs.FontWeight(weight);
}
// Method Description:

View File

@@ -15,6 +15,7 @@
#include "../buffer/out/search.h"
#include "cppwinrt_utils.h"
#include "SearchBoxControl.h"
#include "ThrottledFunc.h"
namespace winrt::Microsoft::Terminal::TerminalControl::implementation
{
@@ -135,8 +136,15 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
FontInfoDesired _desiredFont;
FontInfo _actualFont;
bool _isTerminalInitiatedScroll;
std::atomic<bool> _willUpdateScrollBarToMatchViewport;
struct ScrollBarUpdate
{
std::optional<double> newValue;
double newMaximum;
double newMinimum;
double newViewportSize;
};
std::shared_ptr<ThrottledFunc<ScrollBarUpdate>> _updateScrollBar;
bool _isInternalScrollBarUpdate;
int _rowsToScroll;
@@ -174,7 +182,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
void _ApplyUISettings();
void _InitializeBackgroundBrush();
winrt::fire_and_forget _BackgroundColorChanged(const COLORREF color);
winrt::fire_and_forget _BackgroundColorChanged(const uint32_t color);
bool _InitializeTerminal();
void _UpdateFont(const bool initialUpdate = false);
void _SetFontSize(int fontSize);
@@ -200,7 +208,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
void _DoResizeUnderLock(const double newWidth, const double newHeight);
void _RefreshSizeUnderLock();
void _TerminalTitleChanged(const std::wstring_view& wstr);
winrt::fire_and_forget _TerminalScrollPositionChanged(const int viewTop, const int viewHeight, const int bufferSize);
void _TerminalScrollPositionChanged(const int viewTop, const int viewHeight, const int bufferSize);
winrt::fire_and_forget _TerminalCursorPositionChanged();
void _MouseScrollHandler(const double mouseDelta, const Windows::Foundation::Point point, const bool isLeftButtonPressed);
@@ -215,7 +223,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
void _TryStopAutoScroll(const uint32_t pointerId);
void _UpdateAutoScroll(Windows::Foundation::IInspectable const& sender, Windows::Foundation::IInspectable const& e);
void _ScrollbarUpdater(Windows::UI::Xaml::Controls::Primitives::ScrollBar scrollbar, const int viewTop, const int viewHeight, const int bufferSize);
static Windows::UI::Xaml::Thickness _ParseThicknessFromPadding(const hstring padding);
::Microsoft::Terminal::Core::ControlKeyStates _GetPressedModifierKeys() const;

View File

@@ -18,7 +18,7 @@
Microsoft namespace. This is, obviously, not great. None of our other
projects compile properly when they depend on this "Microsoft.winmd."
-->
<CppWinRTNamespaceMergeDepth>4</CppWinRTNamespaceMergeDepth>
<CppWinRTNamespaceMergeDepth>3</CppWinRTNamespaceMergeDepth>
<!--
DON'T REDIRECT OUR OUTPUT.
@@ -43,6 +43,8 @@
<ClInclude Include="TermControlAutomationPeer.h">
<DependentUpon>TermControlAutomationPeer.idl</DependentUpon>
</ClInclude>
<ClInclude Include="ThreadSafeOptional.h" />
<ClInclude Include="ThrottledFunc.h" />
<ClInclude Include="TSFInputControl.h">
<DependentUpon>TSFInputControl.xaml</DependentUpon>
</ClInclude>
@@ -86,7 +88,8 @@
<None Include="TerminalControl.def" />
</ItemGroup>
<ItemGroup>
<PRIResource Include="Resources\*\Resources.resw" />
<PRIResource Include="Resources\en-US\Resources.resw" />
<OCResourceDirectory Include="Resources" />
</ItemGroup>
<!-- ========================= Project References ======================== -->
<ItemGroup>
@@ -133,4 +136,6 @@
<AdditionalIncludeDirectories>$(OpenConsoleDir)src\cascadia\inc;$(OpenConsoleDir)src\types\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<Import Project="$(SolutionDir)build\rules\CollectWildcardResources.targets" />
</Project>

View File

@@ -26,6 +26,8 @@
<ClInclude Include="TermControlAutomationPeer.h" />
<ClInclude Include="XamlUiaTextRange.h" />
<ClInclude Include="TermControlUiaProvider.hpp" />
<ClInclude Include="ThreadSafeOptional.h" />
<ClInclude Include="ThrottledFunc.h" />
<ClInclude Include="UiaTextRange.hpp" />
</ItemGroup>
<ItemGroup>
@@ -45,7 +47,7 @@
<Natvis Include="$(SolutionDir)tools\ConsoleTypes.natvis" />
</ItemGroup>
<ItemGroup>
<PRIResource Include="Resources\*\Resources.resw">
<PRIResource Include="Resources\en-US\Resources.resw">
<Filter>Resources</Filter>
</PRIResource>
</ItemGroup>

View File

@@ -0,0 +1,54 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "pch.h"
template<typename T>
class ThreadSafeOptional
{
public:
template<class... Args>
bool Emplace(Args&&... args)
{
std::lock_guard guard{ _lock };
bool hadValue = _inner.has_value();
_inner.emplace(std::forward<Args>(args)...);
return !hadValue;
}
std::optional<T> Take()
{
std::lock_guard guard{ _lock };
std::optional<T> value;
_inner.swap(value);
return value;
}
// Method Description:
// - If the optional has a value, then call the specified function with a
// reference to the value.
// - This method is always thread-safe. It can be called multiple times on
// different threads.
// Arguments:
// - f: the function to call with a reference to the value
// Return Value:
// - <none>
template<typename F>
void ModifyValue(F f)
{
std::lock_guard guard{ _lock };
if (_inner.has_value())
{
f(_inner.value());
}
}
private:
std::mutex _lock;
std::optional<T> _inner;
};

View File

@@ -0,0 +1,97 @@
/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Module Name:
- ThrottledFunc.h
Abstract:
- This module defines a class to throttle function calls.
- You create an instance of a `ThrottledFunc` with a function and the delay
between two function calls.
- The function takes an argument of type `T`, the template argument of
`ThrottledFunc`.
- Use the `Run` method to wait and then call the function.
--*/
#pragma once
#include "pch.h"
#include "ThreadSafeOptional.h"
template<typename T>
class ThrottledFunc : public std::enable_shared_from_this<ThrottledFunc<T>>
{
public:
using Func = std::function<void(T arg)>;
ThrottledFunc(Func func, winrt::Windows::Foundation::TimeSpan delay) :
_func{ func },
_delay{ delay }
{
}
// Method Description:
// - Runs the function later with the specified argument, except if `Run`
// is called again before with a new argument, in which case the new
// argument will be instead.
// - For more information, read the "Abstract" section in the header file.
// Arguments:
// - arg: the argument to pass to the function
// Return Value:
// - <none>
winrt::fire_and_forget Run(T arg)
{
if (!_pendingCallArg.Emplace(arg))
{
// already pending
return;
}
auto weakThis = this->weak_from_this();
co_await winrt::resume_after(_delay);
if (auto self{ weakThis.lock() })
{
auto arg = self->_pendingCallArg.Take();
if (arg.has_value())
{
self->_func(arg.value());
}
else
{
// should not happen
}
}
}
// Method Description:
// - Modifies the pending argument for the next function invocation, if
// there is one pending currently.
// - Let's say that you just called the `Run` method with argument A.
// After the delay specified in the constructor, the function R
// specified in the constructor will be called with argument A.
// - By using this method, you can modify argument A before the function R
// is called with argument A.
// - You pass a function to this method which will take a reference to
// argument A and will modify it.
// - When there is no pending invocation of function R, this method will
// not do anything.
// - This method is always thread-safe. It can be called multiple times on
// different threads.
// Arguments:
// - f: the function to call with a reference to the argument
// Return Value:
// - <none>
template<typename F>
void ModifyPending(F f)
{
_pendingCallArg.ModifyValue(f);
}
private:
Func _func;
winrt::Windows::Foundation::TimeSpan _delay;
ThreadSafeOptional<T> _pendingCallArg;
};

View File

@@ -755,48 +755,49 @@ void Terminal::_AdjustCursorPosition(const COORD proposedPosition)
auto proposedCursorPosition = proposedPosition;
auto& cursor = _buffer->GetCursor();
const Viewport bufferSize = _buffer->GetSize();
bool notifyScroll = false;
// If we're about to scroll past the bottom of the buffer, instead cycle the
// buffer.
// GH#5540 - Make sure this is a positive number. We can't create a
// negative number of new rows.
const auto newRows = std::max(0, proposedCursorPosition.Y - bufferSize.Height() + 1);
if (newRows > 0)
SHORT rowsPushedOffTopOfBuffer = 0;
if (proposedCursorPosition.Y >= bufferSize.Height())
{
const auto newRows = proposedCursorPosition.Y - bufferSize.Height() + 1;
for (auto dy = 0; dy < newRows; dy++)
{
_buffer->IncrementCircularBuffer();
proposedCursorPosition.Y--;
rowsPushedOffTopOfBuffer++;
}
notifyScroll = true;
}
// Update Cursor Position
cursor.SetPosition(proposedCursorPosition);
const COORD cursorPosAfter = cursor.GetPosition();
// Move the viewport down if the cursor moved below the viewport.
if (cursorPosAfter.Y > _mutableViewport.BottomInclusive())
bool updatedViewport = false;
if (proposedCursorPosition.Y > _mutableViewport.BottomInclusive())
{
const auto newViewTop = std::max(0, cursorPosAfter.Y - (_mutableViewport.Height() - 1));
const auto newViewTop = std::max(0, proposedCursorPosition.Y - (_mutableViewport.Height() - 1));
if (newViewTop != _mutableViewport.Top())
{
_mutableViewport = Viewport::FromDimensions({ 0, gsl::narrow<short>(newViewTop) },
_mutableViewport.Dimensions());
notifyScroll = true;
updatedViewport = true;
}
}
if (notifyScroll)
if (updatedViewport)
{
_NotifyScrollEvent();
}
if (rowsPushedOffTopOfBuffer != 0)
{
// We have to report the delta here because we might have circled the text buffer.
// That didn't change the viewport and therefore the TriggerScroll(void)
// method can't detect the delta on its own.
COORD delta{ 0, -gsl::narrow<SHORT>(newRows) };
COORD delta{ 0, -rowsPushedOffTopOfBuffer };
_buffer->GetRenderTarget().TriggerScroll(&delta);
_NotifyScrollEvent();
}
_NotifyTerminalCursorPositionChanged();
@@ -875,7 +876,7 @@ void Terminal::SetCursorPositionChangedCallback(std::function<void()> pfn) noexc
// - Allows setting a callback for when the background color is changed
// Arguments:
// - pfn: a function callback that takes a uint32 (DWORD COLORREF) color in the format 0x00BBGGRR
void Terminal::SetBackgroundCallback(std::function<void(const COLORREF)> pfn) noexcept
void Terminal::SetBackgroundCallback(std::function<void(const uint32_t)> pfn) noexcept
{
_pfnBackgroundColorChanged.swap(pfn);
}

View File

@@ -36,7 +36,7 @@ namespace TerminalCoreUnitTests
class TerminalBufferTests;
class TerminalApiTest;
class ConptyRoundtripTests;
class TerminalAndRendererTests;
class ScrollTest;
};
#endif
@@ -171,7 +171,7 @@ public:
void SetTitleChangedCallback(std::function<void(const std::wstring_view&)> pfn) noexcept;
void SetScrollPositionChangedCallback(std::function<void(const int, const int, const int)> pfn) noexcept;
void SetCursorPositionChangedCallback(std::function<void()> pfn) noexcept;
void SetBackgroundCallback(std::function<void(const COLORREF)> pfn) noexcept;
void SetBackgroundCallback(std::function<void(const uint32_t)> pfn) noexcept;
void SetCursorOn(const bool isOn);
bool IsCursorBlinkingAllowed() const noexcept;
@@ -196,7 +196,7 @@ private:
std::function<void(std::wstring&)> _pfnWriteInput;
std::function<void(const std::wstring_view&)> _pfnTitleChanged;
std::function<void(const int, const int, const int)> _pfnScrollPositionChanged;
std::function<void(const COLORREF)> _pfnBackgroundColorChanged;
std::function<void(const uint32_t)> _pfnBackgroundColorChanged;
std::function<void()> _pfnCursorPositionChanged;
std::unique_ptr<::Microsoft::Console::VirtualTerminal::StateMachine> _stateMachine;
@@ -297,6 +297,6 @@ private:
friend class TerminalCoreUnitTests::TerminalBufferTests;
friend class TerminalCoreUnitTests::TerminalApiTest;
friend class TerminalCoreUnitTests::ConptyRoundtripTests;
friend class TerminalCoreUnitTests::TerminalAndRendererTests;
friend class TerminalCoreUnitTests::ScrollTest;
#endif
};

View File

@@ -44,7 +44,7 @@ bool Terminal::SetTextToDefaults(bool foreground, bool background) noexcept
bool Terminal::SetTextForegroundIndex(BYTE colorIndex) noexcept
{
TextAttribute attrs = _buffer->GetCurrentAttributes();
attrs.SetIndexedForeground(colorIndex);
attrs.SetIndexedAttributes({ colorIndex }, {});
_buffer->SetCurrentAttributes(attrs);
return true;
}
@@ -52,7 +52,7 @@ bool Terminal::SetTextForegroundIndex(BYTE colorIndex) noexcept
bool Terminal::SetTextBackgroundIndex(BYTE colorIndex) noexcept
{
TextAttribute attrs = _buffer->GetCurrentAttributes();
attrs.SetIndexedBackground(colorIndex);
attrs.SetIndexedAttributes({}, { colorIndex });
_buffer->SetCurrentAttributes(attrs);
return true;
}
@@ -68,7 +68,14 @@ bool Terminal::SetTextRgbColor(COLORREF color, bool foreground) noexcept
bool Terminal::BoldText(bool boldOn) noexcept
{
TextAttribute attrs = _buffer->GetCurrentAttributes();
attrs.SetBold(boldOn);
if (boldOn)
{
attrs.Embolden();
}
else
{
attrs.Debolden();
}
_buffer->SetCurrentAttributes(attrs);
return true;
}
@@ -76,7 +83,11 @@ bool Terminal::BoldText(bool boldOn) noexcept
bool Terminal::UnderlineText(bool underlineOn) noexcept
{
TextAttribute attrs = _buffer->GetCurrentAttributes();
attrs.SetUnderline(underlineOn);
WORD metaAttrs = attrs.GetMetaAttributes();
WI_UpdateFlag(metaAttrs, COMMON_LVB_UNDERSCORE, underlineOn);
attrs.SetMetaAttributes(metaAttrs);
_buffer->SetCurrentAttributes(attrs);
return true;
}
@@ -84,7 +95,11 @@ bool Terminal::UnderlineText(bool underlineOn) noexcept
bool Terminal::ReverseText(bool reversed) noexcept
{
TextAttribute attrs = _buffer->GetCurrentAttributes();
attrs.SetReverseVideo(reversed);
WORD metaAttrs = attrs.GetMetaAttributes();
WI_UpdateFlag(metaAttrs, COMMON_LVB_REVERSE_VIDEO, reversed);
attrs.SetMetaAttributes(metaAttrs);
_buffer->SetCurrentAttributes(attrs);
return true;
}

View File

@@ -60,7 +60,7 @@ const COLORREF Terminal::GetBackgroundColor(const TextAttribute& attr) const noe
const auto bgColor = attr.CalculateRgbBackground({ _colorTable.data(), _colorTable.size() }, _defaultFg, _defaultBg);
// We only care about alpha for the default BG (which enables acrylic)
// If the bg isn't the default bg color, or reverse video is enabled, make it fully opaque.
if (!attr.BackgroundIsDefault() || attr.IsReverseVideo())
if (!attr.BackgroundIsDefault() || WI_IsFlagSet(attr.GetMetaAttributes(), COMMON_LVB_REVERSE_VIDEO))
{
return 0xff000000 | bgColor;
}

View File

@@ -34,7 +34,6 @@ namespace Microsoft.Terminal.Settings
String FontFace;
Int32 FontSize;
Windows.UI.Text.FontWeight FontWeight;
String Padding;
IKeyBindings KeyBindings;

View File

@@ -34,7 +34,6 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
_padding{ DEFAULT_PADDING },
_fontFace{ DEFAULT_FONT_FACE },
_fontSize{ DEFAULT_FONT_SIZE },
_fontWeight{ DEFAULT_FONT_WEIGHT },
_backgroundImage{},
_backgroundImageOpacity{ 1.0 },
_backgroundImageStretchMode{ winrt::Windows::UI::Xaml::Media::Stretch::UniformToFill },
@@ -259,16 +258,6 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
_fontSize = value;
}
winrt::Windows::UI::Text::FontWeight TerminalSettings::FontWeight() noexcept
{
return _fontWeight;
}
void TerminalSettings::FontWeight(winrt::Windows::UI::Text::FontWeight value) noexcept
{
_fontWeight = value;
}
void TerminalSettings::BackgroundImage(hstring const& value)
{
_backgroundImage = value;

View File

@@ -68,8 +68,6 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
void FontFace(hstring const& value);
int32_t FontSize() noexcept;
void FontSize(int32_t value) noexcept;
winrt::Windows::UI::Text::FontWeight FontWeight() noexcept;
void FontWeight(winrt::Windows::UI::Text::FontWeight value) noexcept;
hstring BackgroundImage();
void BackgroundImage(hstring const& value);
@@ -135,7 +133,6 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
double _tintOpacity;
hstring _fontFace;
int32_t _fontSize;
winrt::Windows::UI::Text::FontWeight _fontWeight;
hstring _padding;
hstring _backgroundImage;
double _backgroundImageOpacity;

View File

@@ -1,30 +0,0 @@
#include "pch.h"
#include "ColorSchemes.h"
#if __has_include("ColorSchemes.g.cpp")
#include "ColorSchemes.g.cpp"
#endif
using namespace winrt::Windows::UI::Xaml;
namespace winrt::Microsoft::Terminal::Settings::Control::implementation
{
ColorSchemes::ColorSchemes()
{
InitializeComponent();
}
int32_t ColorSchemes::MyProperty()
{
throw hresult_not_implemented();
}
void ColorSchemes::MyProperty(int32_t /* value */)
{
throw hresult_not_implemented();
}
void ColorSchemes::ClickHandler(IInspectable const&, RoutedEventArgs const&)
{
//Button().Content(box_value(L"Clicked"));
}
}

View File

@@ -1,23 +0,0 @@
#pragma once
#include "ColorSchemes.g.h"
namespace winrt::Microsoft::Terminal::Settings::Control::implementation
{
struct ColorSchemes : ColorSchemesT<ColorSchemes>
{
ColorSchemes();
int32_t MyProperty();
void MyProperty(int32_t value);
void ClickHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);
};
}
namespace winrt::Microsoft::Terminal::Settings::Control::factory_implementation
{
struct ColorSchemes : ColorSchemesT<ColorSchemes, implementation::ColorSchemes>
{
};
}

View File

@@ -1,9 +0,0 @@
namespace Microsoft.Terminal.Settings.Control
{
[default_interface]
runtimeclass ColorSchemes : Windows.UI.Xaml.Controls.Page
{
ColorSchemes();
Int32 MyProperty;
}
}

View File

@@ -1,48 +0,0 @@
<Page
x:Class="Microsoft.Terminal.Settings.Control.ColorSchemes"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Microsoft.Terminal.Settings"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<RelativePanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBlock x:Name="TitleTextBox"
Text="Color Schemes"
Style="{StaticResource HeaderTextBlockStyle}"
Margin="0,0,0,8" />
<GridView x:Name="ProfilesGridView"
Margin="0,0,0,8"
RelativePanel.AlignLeftWithPanel="True"
RelativePanel.AlignRightWithPanel="True"
RelativePanel.Below="TitleTextBox">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid x:Name="MaxItemsWrapGrid"
MaximumRowsOrColumns="2"
Orientation="Horizontal"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<Image Source="Assets/AllTerminalColorSchemes (2).png"
Stretch="Uniform"
Width="300"/>
<Image Source="Assets/AllTerminalColorSchemes (3).png"
Stretch="Uniform"
Width="300"/>
<Image Source="Assets/AllTerminalColorSchemes (4).png"
Stretch="Uniform"
Width="300"/>
<Image Source="Assets/AllTerminalColorSchemes (5).png"
Stretch="Uniform"
Width="300"/>
<Image Source="Assets/AllTerminalColorSchemes (6).png"
Stretch="Uniform"
Width="300"/>
<Image Source="Assets/AllTerminalColorSchemes (7).png"
Stretch="Uniform"
Width="300"/>
</GridView>
</RelativePanel>
</Page>

View File

@@ -1,29 +0,0 @@
#include "pch.h"
#include "Globals.h"
#include "Globals.g.cpp"
using namespace winrt;
using namespace winrt::Windows::UI::Xaml;
namespace winrt::Microsoft::Terminal::Settings::Control::implementation
{
Globals::Globals()
{
InitializeComponent();
}
int32_t Globals::MyProperty()
{
throw hresult_not_implemented();
}
void Globals::MyProperty(int32_t /* value */)
{
throw hresult_not_implemented();
}
void Globals::ClickHandler(IInspectable const&, RoutedEventArgs const&)
{
}
}

View File

@@ -1,23 +0,0 @@
#pragma once
#include "Globals.g.h"
namespace winrt::Microsoft::Terminal::Settings::Control::implementation
{
struct Globals : GlobalsT<Globals>
{
Globals();
int32_t MyProperty();
void MyProperty(int32_t value);
void ClickHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);
};
}
namespace winrt::Microsoft::Terminal::Settings::Control::factory_implementation
{
struct Globals : GlobalsT<Globals, implementation::Globals>
{
};
}

View File

@@ -1,9 +0,0 @@
namespace Microsoft.Terminal.Settings.Control
{
[default_interface]
runtimeclass Globals : Windows.UI.Xaml.Controls.Page
{
Globals();
Int32 MyProperty;
}
}

View File

@@ -1,80 +0,0 @@
<Page
x:Class="Microsoft.Terminal.Settings.Control.Globals"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Microsoft.Terminal.Settings.Control"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Controls="using:Microsoft.UI.Xaml.Controls"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
Margin="0,12,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<TextBlock Text="Globals"
Style="{StaticResource HeaderTextBlockStyle}"
Margin="0,0,0,10" />
<StackPanel Grid.Row="1" Grid.Column="0" Margin="0,0,100,0">
<TextBlock Text="Appearance"
Style="{StaticResource TitleTextBlockStyle}" Margin="0,0,0,10" />
<Controls:RadioButtons Header="Requested Theme" Margin="0,0,0,10">
<RadioButton x:Name="SystemTheme" Content="System"/>
<RadioButton x:Name="DarkTheme" Content="Dark"/>
<RadioButton x:Name="LightTheme" Content="Light"/>
</Controls:RadioButtons>
<Controls:RadioButtons Header="Launch mode" Margin="0,0,0,10">
<RadioButton x:Name="DefaultLaunchMode" Content="Default"/>
<RadioButton x:Name="MaximizedLaunchMode" Content="Maximized"/>
</Controls:RadioButtons>
<RelativePanel Margin="0,0,0,10">
<Controls:NumberBox x:Name="InitialCols"
Header="Initial Columns"
Value="120"
SpinButtonPlacementMode="Compact"
SmallChange="10"
LargeChange="100"
Margin="0,0,20,0"/>
<Controls:NumberBox x:Name="InitialRows"
Header="Initial Rows"
Value="30"
SpinButtonPlacementMode="Compact"
SmallChange="10"
LargeChange="100"
Margin="0,0,20,0"
RelativePanel.RightOf="InitialCols"/>
<TextBox Header="Initial position"
RelativePanel.RightOf="InitialRows"/>
</RelativePanel>
<CheckBox Content="Always show tabs" />
<CheckBox Content="Show Terminal title in titlebar" />
<CheckBox Content="Show tabs in titlebar" Margin="0,0,0,10" />
<Controls:RadioButtons Header="Tab width mode">
<RadioButton x:Name="EqualTabWidthMode" Content="Equal"/>
<RadioButton x:Name="TitleLengthTabWidthMode" Content="Title length"/>
</Controls:RadioButtons>
</StackPanel>
<StackPanel Grid.Row="1" Grid.Column="1" Margin="0,0,100,0">
<TextBlock Text="Interaction"
Style="{StaticResource TitleTextBlockStyle}" Margin="0,0,0,10" />
<TextBox Header="Default profile" Margin="0,0,0,10" />
<TextBox Header="Word delimeters" Margin="0,0,0,10" />
<CheckBox Content="Confirm close all tabs" />
<CheckBox Content="Copy on select" />
<CheckBox Content="Snap to grid on resize" Margin="0,0,0,10" />
<Controls:NumberBox x:Name="RowsToScroll"
Header="Rows to scroll"
Value="30"
SpinButtonPlacementMode="Compact"
SmallChange="10"
LargeChange="100"
Width="100" HorizontalAlignment="Left"/>
</StackPanel>
</Grid>
</Page>

View File

@@ -1,30 +0,0 @@
#include "pch.h"
#include "Keybindings.h"
#if __has_include("Keybindings.g.cpp")
#include "Keybindings.g.cpp"
#endif
using namespace winrt::Windows::UI::Xaml;
namespace winrt::Microsoft::Terminal::Settings::Control::implementation
{
Keybindings::Keybindings()
{
InitializeComponent();
}
int32_t Keybindings::MyProperty()
{
throw hresult_not_implemented();
}
void Keybindings::MyProperty(int32_t /* value */)
{
throw hresult_not_implemented();
}
void Keybindings::ClickHandler(IInspectable const&, RoutedEventArgs const&)
{
//Button().Content(box_value(L"Clicked"));
}
}

View File

@@ -1,23 +0,0 @@
#pragma once
#include "Keybindings.g.h"
namespace winrt::Microsoft::Terminal::Settings::Control::implementation
{
struct Keybindings : KeybindingsT<Keybindings>
{
Keybindings();
int32_t MyProperty();
void MyProperty(int32_t value);
void ClickHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);
};
}
namespace winrt::Microsoft::Terminal::Settings::Control::factory_implementation
{
struct Keybindings : KeybindingsT<Keybindings, implementation::Keybindings>
{
};
}

View File

@@ -1,9 +0,0 @@
namespace Microsoft.Terminal.Settings.Control
{
[default_interface]
runtimeclass Keybindings : Windows.UI.Xaml.Controls.Page
{
Keybindings();
Int32 MyProperty;
}
}

View File

@@ -1,19 +0,0 @@
<Page
x:Class="Microsoft.Terminal.Settings.Control.Keybindings"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Microsoft.Terminal.Settings.Control"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
Margin="0,12,0,0">
<StackPanel>
<TextBlock x:Name="TitleTextBox"
Text="Keybindings"
Style="{StaticResource HeaderTextBlockStyle}"
Margin="0,0,0,8" />
</StackPanel>
</Grid>
</Page>

View File

@@ -1,93 +0,0 @@
#include "pch.h"
#include "MainPage.h"
#include "MainPage.g.cpp"
#include "Globals.h"
#include "Profiles.h"
#include "ColorSchemes.h"
#include "Keybindings.h"
using namespace winrt::Windows::UI::Xaml;
namespace winrt::Microsoft::Terminal::Settings::Control::implementation
{
MainPage::MainPage()
{
InitializeComponent();
}
int32_t MainPage::MyProperty()
{
throw hresult_not_implemented();
}
void MainPage::MyProperty(int32_t /* value */)
{
throw hresult_not_implemented();
}
void MainPage::ClickHandler(IInspectable const&, RoutedEventArgs const&)
{
}
void MainPage::SettingsNav_Loaded(IInspectable const&, RoutedEventArgs const&)
{
//// set the initial selectedItem
for (uint32_t i = 0; i < SettingsNav().MenuItems().Size(); i++)
{
const auto item = SettingsNav().MenuItems().GetAt(i).as<Controls::NavigationViewItemBase>();
const hstring globalsNav = L"Globals_Nav";
const hstring itemTag = unbox_value<hstring>(item.Tag());
if (itemTag == globalsNav)
{
item.IsSelected(true);
SettingsNav().Header() = item.Tag();
break;
}
}
contentFrame().Navigate(xaml_typename<Control::Globals>());
}
void MainPage::SettingsNav_SelectionChanged(Controls::NavigationView sender, Controls::NavigationViewSelectionChangedEventArgs args)
{
}
void MainPage::SettingsNav_ItemInvoked(Controls::NavigationView sender, Controls::NavigationViewItemInvokedEventArgs args)
{
Controls::TextBlock item = args.InvokedItem().as<Controls::TextBlock>();
if (item != NULL)
{
const hstring globalsPage = L"Globals_Page";
const hstring profilesPage = L"Profiles_Page";
const hstring colorSchemesPage = L"ColorSchemes_Page";
const hstring keybindingsPage = L"Keybindings_Page";
if (unbox_value<hstring>(item.Tag()) == globalsPage)
{
contentFrame().Navigate(xaml_typename<Control::Globals>());
}
else if (unbox_value<hstring>(item.Tag()) == profilesPage)
{
contentFrame().Navigate(xaml_typename<Control::Profiles>());
}
else if (unbox_value<hstring>(item.Tag()) == colorSchemesPage)
{
contentFrame().Navigate(xaml_typename<Control::ColorSchemes>());
}
else if (unbox_value<hstring>(item.Tag()) == keybindingsPage)
{
contentFrame().Navigate(xaml_typename<Control::Keybindings>());
}
}
}
}
//void winrt::Microsoft::Terminal::Settings::Control::implementation::MainPage::SettingsNav_SelectionChanged(winrt::Windows::UI::Xaml::Controls::NavigationView const& sender, winrt::Windows::UI::Xaml::Controls::NavigationViewSelectionChangedEventArgs const& args)
//{
//
//}

View File

@@ -1,27 +0,0 @@
#pragma once
#include "MainPage.g.h"
#include "winrt/Microsoft.UI.Xaml.Controls.h"
namespace winrt::Microsoft::Terminal::Settings::Control::implementation
{
struct MainPage : MainPageT<MainPage>
{
MainPage();
int32_t MyProperty();
void MyProperty(int32_t value);
void ClickHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);
void SettingsNav_Loaded(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);
void SettingsNav_SelectionChanged(Windows::UI::Xaml::Controls::NavigationView sender, Windows::UI::Xaml::Controls::NavigationViewSelectionChangedEventArgs args);
void SettingsNav_ItemInvoked(Windows::UI::Xaml::Controls::NavigationView sender, Windows::UI::Xaml::Controls::NavigationViewItemInvokedEventArgs args);
};
}
namespace winrt::Microsoft::Terminal::Settings::Control::factory_implementation
{
struct MainPage : MainPageT<MainPage, implementation::MainPage>
{
};
}

View File

@@ -1,9 +0,0 @@
namespace Microsoft.Terminal.Settings.Control
{
[default_interface]
runtimeclass MainPage : Windows.UI.Xaml.Controls.Page
{
MainPage();
Int32 MyProperty;
}
}

View File

@@ -1,52 +0,0 @@
<Page
x:Class="Microsoft.Terminal.Settings.Control.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Microsoft.Terminal.Settings.Control"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
mc:Ignorable="d">
<NavigationView x:Name="SettingsNav"
IsSettingsVisible="False"
Loaded="SettingsNav_Loaded"
SelectionChanged="SettingsNav_SelectionChanged"
ItemInvoked="SettingsNav_ItemInvoked">
<NavigationView.AutoSuggestBox>
<AutoSuggestBox PlaceholderText="Search" QueryIcon="Find"/>
</NavigationView.AutoSuggestBox>
<NavigationView.MenuItems>
<NavigationViewItem Icon="Globe"
Tag="Globals_Nav" >
<TextBlock Tag="Globals_Page">Globals</TextBlock>
</NavigationViewItem>
<NavigationViewItem Tag="Profiles_Nav">
<NavigationViewItem.Icon>
<FontIcon Glyph="&#xE756;" />
</NavigationViewItem.Icon>
<TextBlock Tag="Profiles_Page">Profiles</TextBlock>
</NavigationViewItem>
<NavigationViewItem Tag="ColorSchemes_Nav">
<NavigationViewItem.Icon>
<FontIcon Glyph="&#xE790;"></FontIcon>
</NavigationViewItem.Icon>
<TextBlock Tag="ColorSchemes_Page">Color Schemes</TextBlock>
</NavigationViewItem>
<NavigationViewItem Icon="Keyboard"
Tag="Keybindings_Nav">
<TextBlock Tag="Keybindings_Page">Keybindings</TextBlock>
</NavigationViewItem>
</NavigationView.MenuItems>
<NavigationView.PaneFooter>
<NavigationViewItem>
<NavigationViewItem.Icon>
<FontIcon Glyph="&#xE713;" />
</NavigationViewItem.Icon>
<TextBlock>Open JSON file</TextBlock>
</NavigationViewItem>
</NavigationView.PaneFooter>
<Frame x:Name="contentFrame"
Margin="20"></Frame>
</NavigationView>
</Page>

View File

@@ -1,46 +0,0 @@
#include "pch.h"
#include "Profiles.h"
#include "Profiles.g.cpp"
using namespace winrt::Windows::UI::Xaml;
namespace winrt::Microsoft::Terminal::Settings::Control::implementation
{
Profiles::Profiles()
{
InitializeComponent();
}
Profiles::Profiles(winrt::hstring const& name) : m_name{ name }
{
}
winrt::hstring Profiles::Name()
{
return m_name;
}
void Profiles::Name(winrt::hstring const& value)
{
if (m_name != value)
{
}
}
int32_t Profiles::MyProperty()
{
throw hresult_not_implemented();
}
void Profiles::MyProperty(int32_t /* value */)
{
throw hresult_not_implemented();
}
void Profiles::ClickHandler(IInspectable const&, RoutedEventArgs const&)
{
}
}

View File

@@ -1,29 +0,0 @@
#pragma once
#include "Profiles.g.h"
namespace winrt::Microsoft::Terminal::Settings::Control::implementation
{
struct Profiles : ProfilesT<Profiles>
{
Profiles();
Profiles(winrt::hstring const& name);
int32_t MyProperty();
void MyProperty(int32_t value);
winrt::hstring Name();
void Name(winrt::hstring const& value);
void ClickHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);
private:
winrt::hstring m_name;
};
}
namespace winrt::Microsoft::Terminal::Settings::Control::factory_implementation
{
struct Profiles : ProfilesT<Profiles, implementation::Profiles>
{
};
}

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