mirror of
https://github.com/microsoft/terminal.git
synced 2026-04-16 11:11:03 +00:00
Compare commits
81 Commits
dev/miniks
...
dev/migrie
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6e1ce8de26 | ||
|
|
5e13c37217 | ||
|
|
6328b1adda | ||
|
|
177cf1caae | ||
|
|
75473c50fb | ||
|
|
76cb9654e1 | ||
|
|
e967801cdf | ||
|
|
50cfd84dd2 | ||
|
|
33860f7c1a | ||
|
|
860a3c7b23 | ||
|
|
eae88a9fdb | ||
|
|
137aea367a | ||
|
|
8a93b1dd5d | ||
|
|
6ca7d0e054 | ||
|
|
6f1dc5c9fa | ||
|
|
b5be04c3ae | ||
|
|
48d4e248b7 | ||
|
|
264618ae88 | ||
|
|
f892e52077 | ||
|
|
b90cc38f0f | ||
|
|
92b3453119 | ||
|
|
e25da60775 | ||
|
|
cee5fc9226 | ||
|
|
10e91a823d | ||
|
|
d1a72613c7 | ||
|
|
3e5eb73597 | ||
|
|
cc2fd9b490 | ||
|
|
45243bbee6 | ||
|
|
52eb2e5faa | ||
|
|
8b094fdfde | ||
|
|
7a94b8f725 | ||
|
|
e2f5f75471 | ||
|
|
7ac7fd1de9 | ||
|
|
dd684cbca1 | ||
|
|
edc8b557e1 | ||
|
|
82f968d8d5 | ||
|
|
67c7969879 | ||
|
|
b3d8f0e279 | ||
|
|
10ace041c3 | ||
|
|
4d23121a7e | ||
|
|
414007fdd8 | ||
|
|
72c0601d00 | ||
|
|
b3225db167 | ||
|
|
2517183b63 | ||
|
|
9fbcbcc9d8 | ||
|
|
73aefc18e8 | ||
|
|
a02585da35 | ||
|
|
2cf69338cd | ||
|
|
d71d8d7b32 | ||
|
|
9d411d405c | ||
|
|
58be8cd117 | ||
|
|
487f33ee89 | ||
|
|
829beda501 | ||
|
|
6e6979abe8 | ||
|
|
1fbe8e415d | ||
|
|
fa93fdc034 | ||
|
|
cf6e1f273a | ||
|
|
99059451d8 | ||
|
|
a309191461 | ||
|
|
e1be26b184 | ||
|
|
bc546dbdb0 | ||
|
|
00763fda9e | ||
|
|
b88be4534b | ||
|
|
207666e34d | ||
|
|
62b9a0d1c0 | ||
|
|
02f47f49c3 | ||
|
|
6905065fcf | ||
|
|
0416a944a2 | ||
|
|
3627d8abd5 | ||
|
|
33a9e32736 | ||
|
|
75af4cabbb | ||
|
|
43bd483962 | ||
|
|
0672812e6f | ||
|
|
f53553f4e4 | ||
|
|
11130a4895 | ||
|
|
0886e8f12d | ||
|
|
2e564368c8 | ||
|
|
ead76d7f16 | ||
|
|
614d1b21d6 | ||
|
|
fe640ff894 | ||
|
|
c56eb8fd93 |
@@ -67,12 +67,12 @@ To update the version of a given package, use the following snippet
|
||||
|
||||
where:
|
||||
- `$PackageName` is the name of the package, e.g. Microsoft.UI.Xaml
|
||||
- `$OldVersionNumber` is the version number currently used, e.g. 2.5.0-prerelease.200609001
|
||||
- `$OldVersionNumber` is the version number currently used, e.g. 2.4.2-prerelease.200604001
|
||||
- `$NewVersionNumber` is the version number you want to migrate to, e.g. 2.4.200117003-prerelease
|
||||
|
||||
Example usage:
|
||||
|
||||
`git grep -z -l Microsoft.UI.Xaml | xargs -0 sed -i -e 's/2.5.0-prerelease.200609001/2.4.200117003-prerelease/g'`
|
||||
`git grep -z -l Microsoft.UI.Xaml | xargs -0 sed -i -e 's/2.4.2-prerelease.200604001/2.4.200117003-prerelease/g'`
|
||||
|
||||
## Using .nupkg files instead of downloaded Nuget packages
|
||||
If you want to use .nupkg files instead of the downloaded Nuget package, you can do this with the following steps:
|
||||
|
||||
@@ -9,8 +9,6 @@ Properties listed below affect the entire window, regardless of the profile sett
|
||||
| `alwaysShowTabs` | _Required_ | Boolean | `true` | When set to `true`, tabs are always displayed. When set to `false` and `showTabsInTitlebar` is set to `false`, tabs only appear after typing <kbd>Ctrl</kbd> + <kbd>T</kbd>. |
|
||||
| `copyOnSelect` | Optional | Boolean | `false` | When set to `true`, a selection is immediately copied to your clipboard upon creation. When set to `false`, the selection persists and awaits further action. |
|
||||
| `copyFormatting` | Optional | Boolean | `false` | When set to `true`, the color and font formatting of selected text is also copied to your clipboard. When set to `false`, only plain text is copied to your clipboard. |
|
||||
| `largePasteWarning` | Optional | Boolean | `true` | When set to `true`, trying to paste text with more than 5 KiB of characters will display a warning asking you whether to continue or not with the paste. |
|
||||
| `multiLinePasteWarning` | Optional | Boolean | `true` | When set to `true`, trying to paste text with a _new line_ character will display a warning asking you whether to continue or not with the paste. |
|
||||
| `defaultProfile` | _Required_ | String | PowerShell guid | Sets the default profile. Opens by typing <kbd>Ctrl</kbd> + <kbd>T</kbd> or by clicking the '+' icon. The guid of the desired default profile is used as the value. |
|
||||
| `initialCols` | _Required_ | Integer | `120` | The number of columns displayed in the window upon first load. |
|
||||
| `initialPosition` | Optional | String | `","` | The position of the top left corner of the window upon first load. On a system with multiple displays, these coordinates are relative to the top left of the primary display. If `launchMode` is set to `"maximized"`, the window will be maximized on the monitor specified by those coordinates. |
|
||||
|
||||
@@ -55,12 +55,9 @@
|
||||
"splitPane",
|
||||
"switchToTab",
|
||||
"toggleFullscreen",
|
||||
"toggleRetroEffect",
|
||||
"find",
|
||||
"setTabColor",
|
||||
"openTabColorPicker",
|
||||
"renameTab",
|
||||
"commandPalette",
|
||||
"unbound"
|
||||
],
|
||||
"type": "string"
|
||||
@@ -338,16 +335,6 @@
|
||||
"description": "When set to `true`, the color and font formatting of selected text is also copied to your clipboard. When set to `false`, only plain text is copied to your clipboard.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"largePasteWarning": {
|
||||
"default": true,
|
||||
"description": "When set to true, trying to paste text with more than 5 KiB of characters will display a warning asking you whether to continue or not with the paste.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"multiLinePasteWarning": {
|
||||
"default": true,
|
||||
"description": "When set to true, trying to paste text with a \"new line\" character will display a warning asking you whether to continue or not with the paste.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"defaultProfile": {
|
||||
"description": "Sets the default profile. Opens by clicking the \"+\" icon or typing the key binding assigned to \"newTab\".",
|
||||
"type": "string"
|
||||
|
||||
@@ -1,122 +0,0 @@
|
||||
---
|
||||
author: Carlos Zamora @carlos-zamora
|
||||
created on: 2019-08-22
|
||||
last updated: 2020-07-06
|
||||
issue id: 980
|
||||
---
|
||||
|
||||
# Snap On Output
|
||||
|
||||
## Abstract
|
||||
|
||||
The goal of this change is to determine the Terminal's scroll response to newly generated output.
|
||||
|
||||
Currently, new output causes the Terminal to always scroll to it. Some users want to be able to scroll through the buffer without interruptions.
|
||||
|
||||
## Inspiration
|
||||
|
||||
In ConHost, a selection causes the active process to be completely paused. When the selection is removed, the process continues.
|
||||
|
||||
Typical Unix terminals work differently. Rather than disabling the output, they disable the automatic scrolling. This allows the user to continue to see more output by choice.
|
||||
|
||||
## Solution Design
|
||||
|
||||
By default, the viewport will scroll to new output if the following conditions are met:
|
||||
- no selection is active
|
||||
- the viewport is at the "virtual bottom" (the bottom of the scroll history)
|
||||
|
||||
This behavior will not be configurable. If the user wants the viewport to stop autoscrolling, the user will simply create a selection or scroll any distance above the virtual bottom. Conversely, if the user wants the viewport to automatically scroll, the user must scroll to the bottom. Scrolling to the bottom is most easily achieved using the `snapOnInput` functionality.
|
||||
|
||||
Alternative solutions were considered and are recorded below. These solutions may be revisited if users desire an additional level of configurability.
|
||||
|
||||
Researching other terminal emulators has shown that this behavior is not configurable.
|
||||
|
||||
## Alternative Solutions
|
||||
|
||||
### Solution 1: `snapOnOutput` profile setting - enum flags
|
||||
`SnapOnOutput` will be a profile-level `ICoreSettings` setting of type enum or enum array. It can be set to one or multiple of the following values:
|
||||
- `never`: new output does not cause the viewport to update to the bottom of the scroll region
|
||||
- `noSelection`: new output causes the viewport to update to the bottom of the scroll region **IF** no selection is active
|
||||
- `atBottom`: new output causes the viewport to update **IF** the viewport is already at the virtual bottom
|
||||
- `always`: new output causes the viewport to update to the bottom of the scroll region
|
||||
|
||||
The `TerminalCore` is responsible for moving the viewport on a scroll event. All of the logic for this feature should be handled here.
|
||||
|
||||
A new private enum array `_snapOnOutput` will be introduced to save which of these settings are included. The `_NotifyScrollEvent()` calls (and nearby code) will be surrounded by conditional checks for the enums above. This allows it to be used to determine if the viewport should update given a specific situation.
|
||||
|
||||
The `snapOnOutput` setting is introduced as a profile setting to match `snapOnInput`.
|
||||
|
||||
The default `snapOnOutput` value will be `[ "noSelection", "atBottom" ]`.
|
||||
|
||||
When an enum array is defined in the settings, it will be interpreted using boolean logic. The following scenarios will be invalid using the FlagMapper:
|
||||
- `[ "always", "atBottom" ]`
|
||||
- `[ "never", "atBottom" ]`
|
||||
|
||||
### Solution 2: `scrollLock` keybinding action
|
||||
|
||||
A `scrollLock` keybinding action would toggle automatically scrolling to new output.
|
||||
|
||||
**NOTE**: This can be easily confused with the <kbd>ScrollLock</kbd> key. Researching the use of the <kbd>ScrollLock</kbd> key has shown that programs rarely use this key. In most apps, pressing the <kbd>ScrollLock</kbd> key does not actually prevent scrolling the application. Additionally, finding a way to bing the `scrollLock` action to the <kbd>ScrollLock</kbd> key would be difficult. A physical keyboard may not necessarily have a <kbd>ScrollLock</kbd> key. Also, we would have to poll for the internal state of "is the scroll lock key enabled", which may change while the user is not necessarily using Terminal.
|
||||
|
||||
The introduction of a `scrollLock` action would require a visual indicator for the user to know when scrolling has been disabled. However, this introduces a number of problems:
|
||||
- if the indicator is persistent, it may block the view
|
||||
- if the indicator is not persistent, the user may be unaware of being in a state where scrolling doesn't work properly
|
||||
|
||||
**Additionally relevant research**:
|
||||
- In Unix consoles, <kbd>ctrl+s</kbd> and <kbd>ctrl+q</kbd> freeze and unfreeze output respectively. However, this is a feature that is implemented outside of the scope for Terminal. Other shells like PowerShell do not have this feature, for example. There, <kbd>ctrl+s</kbd> does a 'Forward Search History' instead.
|
||||
- Additionally, there is a <kbd>Pause</kbd> key that pauses the output in the conhost console. Pressing any other key will resume scrolling.
|
||||
|
||||
|
||||
## Capabilities
|
||||
|
||||
### Accessibility
|
||||
|
||||
N/A
|
||||
|
||||
### Security
|
||||
|
||||
N/A
|
||||
|
||||
### Reliability
|
||||
|
||||
N/A
|
||||
|
||||
### Compatibility
|
||||
|
||||
N/A
|
||||
|
||||
### Performance, Power, and Efficiency
|
||||
|
||||
N/A
|
||||
|
||||
## Potential Issues
|
||||
|
||||
### Circling the buffer
|
||||
If the text buffer fills up, the text buffer begins 'circling'. This means that new output shifts lines of the buffer up to make space. In a case like this, if `snapOnOutput` is set to `never`, the viewport should actually scroll up to keep the same content on the viewport.
|
||||
|
||||
In the event that the buffer is circling and the viewport has been moved to the top of the buffer, that content of the buffer is now lost (as the 'Infinite Scrollback' feature does not exist or is disabled). At that point, the viewport will remain at the top of the buffer and the new output will push old output out of the buffer.
|
||||
|
||||
### Infinite Scrollback
|
||||
See **Future considerations** > **Infinite Scrollback**.
|
||||
|
||||
## Future considerations
|
||||
|
||||
### Extensibility
|
||||
The introduction of `enum SnapOnOutput` allows for this feature to be enabled/disabled in more complex scenarios. A potential extension would be to introduce a new UI element or keybinding to toggle this feature.
|
||||
|
||||
### Infinite Scrollback
|
||||
At the time of introducing this, the infinite scrollback feature is not supported. This means that the buffer saves the history up to the `historySize` amount of lines. When infinite scrollback is introduced, the buffer needs to change its own contents to allow the user to scroll beyond the `historySize`. With infinite scrollback enabled and the mutable viewport **NOT** snapping to new output, the `TerminalCore` needs to keep track of...
|
||||
- what contents are currently visible to the user (in the current location of the mutable viewport)
|
||||
- how to respond to a user's action of changing the location of the mutable viewport (i.e.: snapOnInput, scroll up/down)
|
||||
|
||||
### Private Mode Escape Sequences
|
||||
There are a couple of private mode escape sequences that some terminals use to control this kind of thing. DECSET 1010, for example, snaps the viewport to the bottom on output, whereas DECSET 1011 spans the viewport to the bottom on a keypress.
|
||||
|
||||
DECSET 1010 should set the `SnapOnOutput` value via a Terminal API.
|
||||
DECSET 1011 should set the `SnapOnInput` value via a Terminal API.
|
||||
|
||||
## Resources
|
||||
|
||||
[GH#980](https://github.com/microsoft/terminal/issues/980)
|
||||
[DECSET 1010](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h4-Functions-using-CSI-_-ordered-by-the-final-character-lparen-s-rparen:CSI-?-Pm-h:Ps-=-1-0-1-0.1F79)
|
||||
[DECSET 1011](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h4-Functions-using-CSI-_-ordered-by-the-final-character-lparen-s-rparen:CSI-?-Pm-h:Ps-=-1-0-1-1.1F7A)
|
||||
BIN
res/Cascadia.ttf
BIN
res/Cascadia.ttf
Binary file not shown.
Binary file not shown.
@@ -17,5 +17,5 @@ Please consult the [license](https://raw.githubusercontent.com/microsoft/cascadi
|
||||
|
||||
### Fonts Included
|
||||
|
||||
* Cascadia Code, Cascadia Mono (2007.01)
|
||||
* from microsoft/cascadia-code@311cc603f30635da704b6a7d13050e245e61667b
|
||||
* Cascadia Code, Cascadia Mono (2005.15)
|
||||
* from microsoft/cascadia-code@0610f2df4356200adb93cb5bca2221b92ad6ee7e
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include "targetver.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
|
||||
// TODO: reference additional headers your program requires here
|
||||
|
||||
@@ -108,12 +108,7 @@ TextAttribute ATTR_ROW::GetAttrByColumn(const size_t column,
|
||||
{
|
||||
THROW_HR_IF(E_INVALIDARG, column >= _cchRowWidth);
|
||||
const auto runPos = FindAttrIndex(column, pApplies);
|
||||
return GetAttrByIndex(runPos);
|
||||
}
|
||||
|
||||
TextAttribute ATTR_ROW::GetAttrByIndex(const size_t index) const
|
||||
{
|
||||
return _list.at(index).GetAttributes();
|
||||
return _list.at(runPos).GetAttributes();
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
@@ -255,11 +250,11 @@ void ATTR_ROW::ReplaceAttrs(const TextAttribute& toBeReplacedAttr, const TextAtt
|
||||
if (newAttrs.size() == 1)
|
||||
{
|
||||
// Get the new color attribute we're trying to apply
|
||||
const TextAttribute NewAttr = newAttrs[0].GetAttributes();
|
||||
const TextAttribute NewAttr = newAttrs.at(0).GetAttributes();
|
||||
|
||||
// If the existing run was only 1 element...
|
||||
// ...and the new color is the same as the old, we don't have to do anything and can exit quick.
|
||||
if (_list.size() == 1 && _list[0].GetAttributes() == NewAttr)
|
||||
if (_list.size() == 1 && _list.at(0).GetAttributes() == NewAttr)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -36,8 +36,6 @@ public:
|
||||
TextAttribute GetAttrByColumn(const size_t column,
|
||||
size_t* const pApplies) const;
|
||||
|
||||
TextAttribute GetAttrByIndex(const size_t index) const;
|
||||
|
||||
size_t GetNumberOfRuns() const noexcept;
|
||||
|
||||
size_t FindAttrIndex(const size_t index,
|
||||
|
||||
@@ -233,9 +233,7 @@ void CharRow::ClearGlyph(const size_t column)
|
||||
// - Note: will throw exception if column is out of bounds
|
||||
const CharRow::reference CharRow::GlyphAt(const size_t column) const
|
||||
{
|
||||
#ifdef DBG
|
||||
THROW_HR_IF(E_INVALIDARG, column >= _data.size());
|
||||
#endif
|
||||
return { const_cast<CharRow&>(*this), column };
|
||||
}
|
||||
|
||||
@@ -248,9 +246,7 @@ const CharRow::reference CharRow::GlyphAt(const size_t column) const
|
||||
// - Note: will throw exception if column is out of bounds
|
||||
CharRow::reference CharRow::GlyphAt(const size_t column)
|
||||
{
|
||||
#ifdef DBG
|
||||
THROW_HR_IF(E_INVALIDARG, column >= _data.size());
|
||||
#endif
|
||||
return { *this, column };
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ CharRowCellReference::operator std::wstring_view() const
|
||||
// - ref to the CharRowCell
|
||||
CharRowCell& CharRowCellReference::_cellData()
|
||||
{
|
||||
return _parent._data[_index];
|
||||
return _parent._data.at(_index);
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
@@ -50,7 +50,7 @@ CharRowCell& CharRowCellReference::_cellData()
|
||||
// - ref to the CharRowCell
|
||||
const CharRowCell& CharRowCellReference::_cellData() const
|
||||
{
|
||||
return _parent._data[_index];
|
||||
return _parent._data.at(_index);
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
|
||||
@@ -169,33 +169,42 @@ OutputCellIterator::OutputCellIterator(const std::basic_string_view<OutputCell>
|
||||
// - True if the views on dereference are valid. False if it shouldn't be dereferenced.
|
||||
OutputCellIterator::operator bool() const noexcept
|
||||
{
|
||||
switch (_mode)
|
||||
try
|
||||
{
|
||||
case Mode::Loose:
|
||||
case Mode::LooseTextOnly: {
|
||||
// In lieu of using start and end, this custom iterator type simply becomes bool false
|
||||
// when we run out of items to iterate over.
|
||||
return _pos < std::get<std::wstring_view>(_run).length();
|
||||
}
|
||||
case Mode::Fill: {
|
||||
if (_fillLimit > 0)
|
||||
switch (_mode)
|
||||
{
|
||||
return _pos < _fillLimit;
|
||||
case Mode::Loose:
|
||||
case Mode::LooseTextOnly:
|
||||
{
|
||||
// In lieu of using start and end, this custom iterator type simply becomes bool false
|
||||
// when we run out of items to iterate over.
|
||||
return _pos < std::get<std::wstring_view>(_run).length();
|
||||
}
|
||||
case Mode::Fill:
|
||||
{
|
||||
if (_fillLimit > 0)
|
||||
{
|
||||
return _pos < _fillLimit;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case Mode::Cell:
|
||||
{
|
||||
return _pos < std::get<std::basic_string_view<OutputCell>>(_run).length();
|
||||
}
|
||||
case Mode::CharInfo:
|
||||
{
|
||||
return _pos < std::get<std::basic_string_view<CHAR_INFO>>(_run).length();
|
||||
}
|
||||
case Mode::LegacyAttr:
|
||||
{
|
||||
return _pos < std::get<std::wstring_view>(_run).length();
|
||||
}
|
||||
default:
|
||||
FAIL_FAST_HR(E_NOTIMPL);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case Mode::Cell: {
|
||||
return _pos < std::get<std::basic_string_view<OutputCell>>(_run).length();
|
||||
}
|
||||
case Mode::CharInfo: {
|
||||
return _pos < std::get<std::basic_string_view<CHAR_INFO>>(_run).length();
|
||||
}
|
||||
case Mode::LegacyAttr: {
|
||||
return _pos < std::get<std::wstring_view>(_run).length();
|
||||
}
|
||||
default:
|
||||
FAIL_FAST_HR(E_NOTIMPL);
|
||||
}
|
||||
CATCH_FAIL_FAST();
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
@@ -209,7 +218,8 @@ OutputCellIterator& OutputCellIterator::operator++()
|
||||
|
||||
switch (_mode)
|
||||
{
|
||||
case Mode::Loose: {
|
||||
case Mode::Loose:
|
||||
{
|
||||
if (!_TryMoveTrailing())
|
||||
{
|
||||
// When walking through a text sequence, we need to move forward by the number of wchar_ts consumed in the previous view
|
||||
@@ -222,7 +232,8 @@ OutputCellIterator& OutputCellIterator::operator++()
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Mode::LooseTextOnly: {
|
||||
case Mode::LooseTextOnly:
|
||||
{
|
||||
if (!_TryMoveTrailing())
|
||||
{
|
||||
// When walking through a text sequence, we need to move forward by the number of wchar_ts consumed in the previous view
|
||||
@@ -235,7 +246,8 @@ OutputCellIterator& OutputCellIterator::operator++()
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Mode::Fill: {
|
||||
case Mode::Fill:
|
||||
{
|
||||
if (!_TryMoveTrailing())
|
||||
{
|
||||
if (_currentView.DbcsAttr().IsTrailing())
|
||||
@@ -257,7 +269,8 @@ OutputCellIterator& OutputCellIterator::operator++()
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Mode::Cell: {
|
||||
case Mode::Cell:
|
||||
{
|
||||
// Walk forward by one because cells are assumed to be in the form they needed to be
|
||||
_pos++;
|
||||
if (operator bool())
|
||||
@@ -266,7 +279,8 @@ OutputCellIterator& OutputCellIterator::operator++()
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Mode::CharInfo: {
|
||||
case Mode::CharInfo:
|
||||
{
|
||||
// Walk forward by one because charinfos are just the legacy version of cells and prealigned to columns
|
||||
_pos++;
|
||||
if (operator bool())
|
||||
@@ -275,7 +289,8 @@ OutputCellIterator& OutputCellIterator::operator++()
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Mode::LegacyAttr: {
|
||||
case Mode::LegacyAttr:
|
||||
{
|
||||
// Walk forward by one because color attributes apply cell by cell (no complex text information)
|
||||
_pos++;
|
||||
if (operator bool())
|
||||
|
||||
@@ -160,95 +160,66 @@ OutputCellIterator ROW::WriteCells(OutputCellIterator it, const size_t index, co
|
||||
// If we're given a right-side column limit, use it. Otherwise, the write limit is the final column index available in the char row.
|
||||
const auto finalColumnInRow = limitRight.value_or(_charRow.size() - 1);
|
||||
|
||||
if (it)
|
||||
while (it && currentIndex <= finalColumnInRow)
|
||||
{
|
||||
// Accumulate usages of the same color so we can spend less time in InsertAttrRuns rewriting it.
|
||||
auto currentColor = it->TextAttr();
|
||||
size_t colorUses = 0;
|
||||
size_t colorStarts = index;
|
||||
|
||||
while (it && currentIndex <= finalColumnInRow)
|
||||
// Fill the color if the behavior isn't set to keeping the current color.
|
||||
if (it->TextAttrBehavior() != TextAttributeBehavior::Current)
|
||||
{
|
||||
// Fill the color if the behavior isn't set to keeping the current color.
|
||||
if (it->TextAttrBehavior() != TextAttributeBehavior::Current)
|
||||
const TextAttributeRun attrRun{ 1, it->TextAttr() };
|
||||
LOG_IF_FAILED(_attrRow.InsertAttrRuns({ &attrRun, 1 },
|
||||
currentIndex,
|
||||
currentIndex,
|
||||
_charRow.size()));
|
||||
}
|
||||
|
||||
// Fill the text if the behavior isn't set to saying there's only a color stored in this iterator.
|
||||
if (it->TextAttrBehavior() != TextAttributeBehavior::StoredOnly)
|
||||
{
|
||||
const bool fillingLastColumn = currentIndex == finalColumnInRow;
|
||||
|
||||
// TODO: MSFT: 19452170 - We need to ensure when writing any trailing byte that the one to the left
|
||||
// is a matching leading byte. Likewise, if we're writing a leading byte, we need to make sure we still have space in this loop
|
||||
// for the trailing byte coming up before writing it.
|
||||
|
||||
// If we're trying to fill the first cell with a trailing byte, pad it out instead by clearing it.
|
||||
// Don't increment iterator. We'll advance the index and try again with this value on the next round through the loop.
|
||||
if (currentIndex == 0 && it->DbcsAttr().IsTrailing())
|
||||
{
|
||||
// If the color of this cell is the same as the run we're currently on,
|
||||
// just increment the counter.
|
||||
if (currentColor == it->TextAttr())
|
||||
{
|
||||
++colorUses;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, commit this color into the run and save off the new one.
|
||||
const TextAttributeRun run{ colorUses, currentColor };
|
||||
// Now commit the new color runs into the attr row.
|
||||
LOG_IF_FAILED(_attrRow.InsertAttrRuns({ &run, 1 },
|
||||
index,
|
||||
currentIndex - 1,
|
||||
_charRow.size()));
|
||||
currentColor = it->TextAttr();
|
||||
colorUses = 1;
|
||||
colorStarts = currentIndex;
|
||||
}
|
||||
_charRow.ClearCell(currentIndex);
|
||||
}
|
||||
|
||||
// Fill the text if the behavior isn't set to saying there's only a color stored in this iterator.
|
||||
if (it->TextAttrBehavior() != TextAttributeBehavior::StoredOnly)
|
||||
// If we're trying to fill the last cell with a leading byte, pad it out instead by clearing it.
|
||||
// Don't increment iterator. We'll exit because we couldn't write a lead at the end of a line.
|
||||
else if (fillingLastColumn && it->DbcsAttr().IsLeading())
|
||||
{
|
||||
const bool fillingLastColumn = currentIndex == finalColumnInRow;
|
||||
|
||||
// TODO: MSFT: 19452170 - We need to ensure when writing any trailing byte that the one to the left
|
||||
// is a matching leading byte. Likewise, if we're writing a leading byte, we need to make sure we still have space in this loop
|
||||
// for the trailing byte coming up before writing it.
|
||||
|
||||
// If we're trying to fill the first cell with a trailing byte, pad it out instead by clearing it.
|
||||
// Don't increment iterator. We'll advance the index and try again with this value on the next round through the loop.
|
||||
if (currentIndex == 0 && it->DbcsAttr().IsTrailing())
|
||||
{
|
||||
_charRow.ClearCell(currentIndex);
|
||||
}
|
||||
// If we're trying to fill the last cell with a leading byte, pad it out instead by clearing it.
|
||||
// Don't increment iterator. We'll exit because we couldn't write a lead at the end of a line.
|
||||
else if (fillingLastColumn && it->DbcsAttr().IsLeading())
|
||||
{
|
||||
_charRow.ClearCell(currentIndex);
|
||||
_charRow.SetDoubleBytePadded(true);
|
||||
}
|
||||
// Otherwise, copy the data given and increment the iterator.
|
||||
else
|
||||
{
|
||||
_charRow.DbcsAttrAt(currentIndex) = it->DbcsAttr();
|
||||
_charRow.GlyphAt(currentIndex) = it->Chars();
|
||||
++it;
|
||||
}
|
||||
|
||||
// If we're asked to (un)set the wrap status and we just filled the last column with some text...
|
||||
// NOTE:
|
||||
// - wrap = std::nullopt --> don't change the wrap value
|
||||
// - wrap = true --> we're filling cells as a steam, consider this a wrap
|
||||
// - wrap = false --> we're filling cells as a block, unwrap
|
||||
if (wrap.has_value() && fillingLastColumn)
|
||||
{
|
||||
// set wrap status on the row to parameter's value.
|
||||
_charRow.SetWrapForced(wrap.value());
|
||||
}
|
||||
_charRow.ClearCell(currentIndex);
|
||||
_charRow.SetDoubleBytePadded(true);
|
||||
}
|
||||
// Otherwise, copy the data given and increment the iterator.
|
||||
else
|
||||
{
|
||||
_charRow.DbcsAttrAt(currentIndex) = it->DbcsAttr();
|
||||
_charRow.GlyphAt(currentIndex) = it->Chars();
|
||||
++it;
|
||||
}
|
||||
|
||||
// Move to the next cell for the next time through the loop.
|
||||
++currentIndex;
|
||||
// If we're asked to (un)set the wrap status and we just filled the last column with some text...
|
||||
// NOTE:
|
||||
// - wrap = std::nullopt --> don't change the wrap value
|
||||
// - wrap = true --> we're filling cells as a steam, consider this a wrap
|
||||
// - wrap = false --> we're filling cells as a block, unwrap
|
||||
if (wrap.has_value() && fillingLastColumn)
|
||||
{
|
||||
// set wrap status on the row to parameter's value.
|
||||
_charRow.SetWrapForced(wrap.value());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
|
||||
// Now commit the final color into the attr row
|
||||
const TextAttributeRun run{ colorUses, currentColor };
|
||||
LOG_IF_FAILED(_attrRow.InsertAttrRuns({ &run, 1 },
|
||||
colorStarts,
|
||||
currentIndex - 1,
|
||||
_charRow.size()));
|
||||
// Move to the next cell for the next time through the loop.
|
||||
++currentIndex;
|
||||
}
|
||||
|
||||
return it;
|
||||
|
||||
@@ -5,33 +5,18 @@
|
||||
#include "TextAttribute.hpp"
|
||||
#include "../../inc/conattrs.hpp"
|
||||
|
||||
BYTE TextAttribute::s_legacyDefaultForeground = 7;
|
||||
BYTE TextAttribute::s_legacyDefaultBackground = 0;
|
||||
|
||||
// Routine Description:
|
||||
// - Sets the legacy attributes which map to and from the default colors.
|
||||
// Parameters:
|
||||
// - defaultAttributes: the attribute values to be used for default colors.
|
||||
// Return value:
|
||||
// - None
|
||||
void TextAttribute::SetLegacyDefaultAttributes(const WORD defaultAttributes) noexcept
|
||||
{
|
||||
s_legacyDefaultForeground = defaultAttributes & FG_ATTRS;
|
||||
s_legacyDefaultBackground = (defaultAttributes & BG_ATTRS) >> 4;
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - Returns a WORD with legacy-style attributes for this textattribute.
|
||||
// Parameters:
|
||||
// - None
|
||||
// - defaultAttributes: the attribute values to be used for default colors.
|
||||
// Return value:
|
||||
// - a WORD with legacy-style attributes for this textattribute.
|
||||
WORD TextAttribute::GetLegacyAttributes() const noexcept
|
||||
WORD TextAttribute::GetLegacyAttributes(const WORD defaultAttributes) const noexcept
|
||||
{
|
||||
const BYTE fgIndex = _foreground.GetLegacyIndex(s_legacyDefaultForeground);
|
||||
const BYTE bgIndex = _background.GetLegacyIndex(s_legacyDefaultBackground);
|
||||
const BYTE fgIndex = _foreground.GetLegacyIndex(defaultAttributes & FG_ATTRS);
|
||||
const BYTE bgIndex = _background.GetLegacyIndex((defaultAttributes & BG_ATTRS) >> 4);
|
||||
const WORD metaAttrs = _wAttrLegacy & META_ATTRS;
|
||||
const bool brighten = IsBold() && _foreground.CanBeBrightened();
|
||||
const bool brighten = _foreground.IsIndex16() && IsBold();
|
||||
return fgIndex | (bgIndex << 4) | metaAttrs | (brighten ? FOREGROUND_INTENSITY : 0);
|
||||
}
|
||||
|
||||
@@ -90,26 +75,6 @@ COLORREF TextAttribute::_GetRgbBackground(std::basic_string_view<COLORREF> color
|
||||
return _background.GetColor(colorTable, defaultColor, false);
|
||||
}
|
||||
|
||||
TextColor TextAttribute::GetForeground() const noexcept
|
||||
{
|
||||
return _foreground;
|
||||
}
|
||||
|
||||
TextColor TextAttribute::GetBackground() const noexcept
|
||||
{
|
||||
return _background;
|
||||
}
|
||||
|
||||
void TextAttribute::SetForeground(const TextColor foreground) noexcept
|
||||
{
|
||||
_foreground = foreground;
|
||||
}
|
||||
|
||||
void TextAttribute::SetBackground(const TextColor background) noexcept
|
||||
{
|
||||
_background = background;
|
||||
}
|
||||
|
||||
void TextAttribute::SetForeground(const COLORREF rgbForeground) noexcept
|
||||
{
|
||||
_foreground = TextColor(rgbForeground);
|
||||
@@ -223,11 +188,6 @@ bool TextAttribute::IsUnderlined() const noexcept
|
||||
return WI_IsFlagSet(_wAttrLegacy, COMMON_LVB_UNDERSCORE);
|
||||
}
|
||||
|
||||
bool TextAttribute::IsOverlined() const noexcept
|
||||
{
|
||||
return WI_IsFlagSet(_wAttrLegacy, COMMON_LVB_GRID_HORIZONTAL);
|
||||
}
|
||||
|
||||
bool TextAttribute::IsReverseVideo() const noexcept
|
||||
{
|
||||
return WI_IsFlagSet(_wAttrLegacy, COMMON_LVB_REVERSE_VIDEO);
|
||||
@@ -264,11 +224,6 @@ void TextAttribute::SetUnderline(bool isUnderlined) noexcept
|
||||
WI_UpdateFlag(_wAttrLegacy, COMMON_LVB_UNDERSCORE, isUnderlined);
|
||||
}
|
||||
|
||||
void TextAttribute::SetOverline(bool isOverlined) noexcept
|
||||
{
|
||||
WI_UpdateFlag(_wAttrLegacy, COMMON_LVB_GRID_HORIZONTAL, isOverlined);
|
||||
}
|
||||
|
||||
void TextAttribute::SetReverseVideo(bool isReversed) noexcept
|
||||
{
|
||||
WI_UpdateFlag(_wAttrLegacy, COMMON_LVB_REVERSE_VIDEO, isReversed);
|
||||
|
||||
@@ -42,8 +42,8 @@ public:
|
||||
|
||||
explicit constexpr TextAttribute(const WORD wLegacyAttr) noexcept :
|
||||
_wAttrLegacy{ gsl::narrow_cast<WORD>(wLegacyAttr & META_ATTRS) },
|
||||
_foreground{ s_LegacyIndexOrDefault(wLegacyAttr & FG_ATTRS, s_legacyDefaultForeground) },
|
||||
_background{ s_LegacyIndexOrDefault((wLegacyAttr & BG_ATTRS) >> 4, s_legacyDefaultBackground) },
|
||||
_foreground{ gsl::narrow_cast<BYTE>(wLegacyAttr & FG_ATTRS), true },
|
||||
_background{ gsl::narrow_cast<BYTE>((wLegacyAttr & BG_ATTRS) >> 4), true },
|
||||
_extendedAttrs{ ExtendedAttributes::Normal }
|
||||
{
|
||||
// If we're given lead/trailing byte information with the legacy color, strip it.
|
||||
@@ -59,8 +59,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
static void SetLegacyDefaultAttributes(const WORD defaultAttributes) noexcept;
|
||||
WORD GetLegacyAttributes() const noexcept;
|
||||
WORD GetLegacyAttributes(const WORD defaultAttributes = 0x07) const noexcept;
|
||||
|
||||
COLORREF CalculateRgbForeground(std::basic_string_view<COLORREF> colorTable,
|
||||
COLORREF defaultFgColor,
|
||||
@@ -95,7 +94,6 @@ public:
|
||||
bool IsInvisible() const noexcept;
|
||||
bool IsCrossedOut() const noexcept;
|
||||
bool IsUnderlined() const noexcept;
|
||||
bool IsOverlined() const noexcept;
|
||||
bool IsReverseVideo() const noexcept;
|
||||
|
||||
void SetBold(bool isBold) noexcept;
|
||||
@@ -104,15 +102,10 @@ public:
|
||||
void SetInvisible(bool isInvisible) noexcept;
|
||||
void SetCrossedOut(bool isCrossedOut) noexcept;
|
||||
void SetUnderline(bool isUnderlined) noexcept;
|
||||
void SetOverline(bool isOverlined) noexcept;
|
||||
void SetReverseVideo(bool isReversed) noexcept;
|
||||
|
||||
ExtendedAttributes GetExtendedAttributes() const noexcept;
|
||||
|
||||
TextColor GetForeground() const noexcept;
|
||||
TextColor GetBackground() const noexcept;
|
||||
void SetForeground(const TextColor foreground) noexcept;
|
||||
void SetBackground(const TextColor background) noexcept;
|
||||
void SetForeground(const COLORREF rgbForeground) noexcept;
|
||||
void SetBackground(const COLORREF rgbBackground) noexcept;
|
||||
void SetIndexedForeground(const BYTE fgIndex) noexcept;
|
||||
@@ -158,14 +151,6 @@ private:
|
||||
COLORREF _GetRgbBackground(std::basic_string_view<COLORREF> colorTable,
|
||||
COLORREF defaultColor) const noexcept;
|
||||
|
||||
static constexpr TextColor s_LegacyIndexOrDefault(const BYTE requestedIndex, const BYTE defaultIndex)
|
||||
{
|
||||
return requestedIndex == defaultIndex ? TextColor{} : TextColor{ requestedIndex, true };
|
||||
}
|
||||
|
||||
static BYTE s_legacyDefaultForeground;
|
||||
static BYTE s_legacyDefaultBackground;
|
||||
|
||||
WORD _wAttrLegacy;
|
||||
TextColor _foreground;
|
||||
TextColor _background;
|
||||
|
||||
@@ -50,11 +50,6 @@ constexpr std::array<BYTE, 256> Index256ToIndex16 = {
|
||||
|
||||
// clang-format on
|
||||
|
||||
bool TextColor::CanBeBrightened() const noexcept
|
||||
{
|
||||
return IsIndex16() || IsDefault();
|
||||
}
|
||||
|
||||
bool TextColor::IsLegacy() const noexcept
|
||||
{
|
||||
return IsIndex16() || (IsIndex256() && _index < 16);
|
||||
@@ -169,7 +164,7 @@ COLORREF TextColor::GetColor(std::basic_string_view<COLORREF> colorTable,
|
||||
}
|
||||
else if (IsRgb())
|
||||
{
|
||||
return GetRGB();
|
||||
return _GetRGB();
|
||||
}
|
||||
else if (IsIndex16() && brighten)
|
||||
{
|
||||
@@ -219,7 +214,7 @@ BYTE TextColor::GetLegacyIndex(const BYTE defaultIndex) const noexcept
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - a COLORREF containing our stored value
|
||||
COLORREF TextColor::GetRGB() const noexcept
|
||||
COLORREF TextColor::_GetRGB() const noexcept
|
||||
{
|
||||
return RGB(_red, _green, _blue);
|
||||
}
|
||||
|
||||
@@ -77,7 +77,6 @@ public:
|
||||
friend constexpr bool operator==(const TextColor& a, const TextColor& b) noexcept;
|
||||
friend constexpr bool operator!=(const TextColor& a, const TextColor& b) noexcept;
|
||||
|
||||
bool CanBeBrightened() const noexcept;
|
||||
bool IsLegacy() const noexcept;
|
||||
bool IsIndex16() const noexcept;
|
||||
bool IsIndex256() const noexcept;
|
||||
@@ -99,8 +98,6 @@ public:
|
||||
return _index;
|
||||
}
|
||||
|
||||
COLORREF GetRGB() const noexcept;
|
||||
|
||||
private:
|
||||
ColorType _meta : 2;
|
||||
union
|
||||
@@ -110,6 +107,8 @@ private:
|
||||
BYTE _green;
|
||||
BYTE _blue;
|
||||
|
||||
COLORREF _GetRGB() const noexcept;
|
||||
|
||||
#ifdef UNIT_TESTING
|
||||
friend class TextBufferTests;
|
||||
template<typename TextColor>
|
||||
@@ -150,7 +149,7 @@ namespace WEX
|
||||
}
|
||||
else if (color.IsRgb())
|
||||
{
|
||||
return WEX::Common::NoThrowString().Format(L"{RGB:0x%06x}", color.GetRGB());
|
||||
return WEX::Common::NoThrowString().Format(L"{RGB:0x%06x}", color._GetRGB());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -33,16 +33,13 @@ TextBuffer::TextBuffer(const COORD screenBufferSize,
|
||||
_cursor{ cursorSize, *this },
|
||||
_storage{},
|
||||
_unicodeStorage{},
|
||||
_renderTarget{ renderTarget },
|
||||
_size{}
|
||||
_renderTarget{ renderTarget }
|
||||
{
|
||||
// initialize ROWs
|
||||
for (size_t i = 0; i < static_cast<size_t>(screenBufferSize.Y); ++i)
|
||||
{
|
||||
_storage.emplace_back(static_cast<SHORT>(i), screenBufferSize.X, _currentAttributes, this);
|
||||
}
|
||||
|
||||
_UpdateSize();
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
@@ -81,7 +78,7 @@ const ROW& TextBuffer::GetRowByOffset(const size_t index) const
|
||||
|
||||
// Rows are stored circularly, so the index you ask for is offset by the start position and mod the total of rows.
|
||||
const size_t offsetIndex = (_firstRow + index) % totalRows;
|
||||
return _storage[offsetIndex];
|
||||
return _storage.at(offsetIndex);
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
@@ -97,7 +94,7 @@ ROW& TextBuffer::GetRowByOffset(const size_t index)
|
||||
|
||||
// Rows are stored circularly, so the index you ask for is offset by the start position and mod the total of rows.
|
||||
const size_t offsetIndex = (_firstRow + index) % totalRows;
|
||||
return _storage[offsetIndex];
|
||||
return _storage.at(offsetIndex);
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
@@ -655,15 +652,9 @@ const SHORT TextBuffer::GetFirstRowIndex() const noexcept
|
||||
{
|
||||
return _firstRow;
|
||||
}
|
||||
|
||||
const Viewport TextBuffer::GetSize() const noexcept
|
||||
const Viewport TextBuffer::GetSize() const
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
|
||||
void TextBuffer::_UpdateSize()
|
||||
{
|
||||
_size = Viewport::FromDimensions({ 0, 0 }, { gsl::narrow<SHORT>(_storage.at(0).size()), gsl::narrow<SHORT>(_storage.size()) });
|
||||
return Viewport::FromDimensions({ 0, 0 }, { gsl::narrow<SHORT>(_storage.at(0).size()), gsl::narrow<SHORT>(_storage.size()) });
|
||||
}
|
||||
|
||||
void TextBuffer::_SetFirstRowIndex(const SHORT FirstRowIndex) noexcept
|
||||
@@ -854,9 +845,6 @@ void TextBuffer::Reset()
|
||||
// Also take advantage of the row ID refresh loop to resize the rows in the X dimension
|
||||
// and cleanup the UnicodeStorage characters that might fall outside the resized buffer.
|
||||
_RefreshRowIDs(newSize.X);
|
||||
|
||||
// Update the cached size value
|
||||
_UpdateSize();
|
||||
}
|
||||
CATCH_RETURN();
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ public:
|
||||
|
||||
const SHORT GetFirstRowIndex() const noexcept;
|
||||
|
||||
const Microsoft::Console::Types::Viewport GetSize() const noexcept;
|
||||
const Microsoft::Console::Types::Viewport GetSize() const;
|
||||
|
||||
void ScrollRows(const SHORT firstRow, const SHORT size, const SHORT delta);
|
||||
|
||||
@@ -177,8 +177,6 @@ public:
|
||||
std::optional<std::reference_wrapper<PositionInformation>> positionInfo);
|
||||
|
||||
private:
|
||||
void _UpdateSize();
|
||||
Microsoft::Console::Types::Viewport _size;
|
||||
std::deque<ROW> _storage;
|
||||
Cursor _cursor;
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ class TextAttributeTests
|
||||
TEST_METHOD(TestRoundtripExhaustive);
|
||||
TEST_METHOD(TestTextAttributeColorGetters);
|
||||
TEST_METHOD(TestReverseDefaultColors);
|
||||
TEST_METHOD(TestRoundtripDefaultColors);
|
||||
|
||||
static const int COLOR_TABLE_SIZE = 16;
|
||||
COLORREF _colorTable[COLOR_TABLE_SIZE];
|
||||
@@ -118,10 +117,13 @@ void TextAttributeTests::TestRoundtripExhaustive()
|
||||
|
||||
auto attr = TextAttribute(wLegacy);
|
||||
|
||||
if (wLegacy != attr.GetLegacyAttributes())
|
||||
bool isLegacy = attr.IsLegacy();
|
||||
bool areEqual = (wLegacy == attr.GetLegacyAttributes());
|
||||
if (!(isLegacy && areEqual))
|
||||
{
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"Failed on wLegacy=0x%x", wLegacy));
|
||||
VERIFY_IS_TRUE(attr.IsLegacy());
|
||||
VERIFY_ARE_EQUAL(wLegacy, attr.GetLegacyAttributes());
|
||||
}
|
||||
}
|
||||
@@ -203,44 +205,3 @@ void TextAttributeTests::TestReverseDefaultColors()
|
||||
VERIFY_ARE_EQUAL(green, attr._GetRgbBackground(view, _defaultBg));
|
||||
VERIFY_ARE_EQUAL(green, attr.CalculateRgbBackground(view, _defaultFg, _defaultBg));
|
||||
}
|
||||
|
||||
void TextAttributeTests::TestRoundtripDefaultColors()
|
||||
{
|
||||
// Set the legacy default colors to yellow on blue.
|
||||
const BYTE fgLegacyDefault = FOREGROUND_RED;
|
||||
const BYTE bgLegacyDefault = BACKGROUND_BLUE;
|
||||
TextAttribute::SetLegacyDefaultAttributes(fgLegacyDefault | bgLegacyDefault);
|
||||
|
||||
WORD legacyAttribute;
|
||||
TextAttribute textAttribute;
|
||||
|
||||
Log::Comment(L"Foreground legacy default index should map to default text color.");
|
||||
legacyAttribute = fgLegacyDefault | BACKGROUND_GREEN;
|
||||
textAttribute.SetDefaultForeground();
|
||||
textAttribute.SetIndexedBackground256(BACKGROUND_GREEN >> 4);
|
||||
VERIFY_ARE_EQUAL(textAttribute, TextAttribute{ legacyAttribute });
|
||||
|
||||
Log::Comment(L"Default foreground text color should map back to legacy default index.");
|
||||
VERIFY_ARE_EQUAL(legacyAttribute, textAttribute.GetLegacyAttributes());
|
||||
|
||||
Log::Comment(L"Background legacy default index should map to default text color.");
|
||||
legacyAttribute = FOREGROUND_GREEN | bgLegacyDefault;
|
||||
textAttribute.SetIndexedForeground256(FOREGROUND_GREEN);
|
||||
textAttribute.SetDefaultBackground();
|
||||
VERIFY_ARE_EQUAL(textAttribute, TextAttribute{ legacyAttribute });
|
||||
|
||||
Log::Comment(L"Default background text color should map back to legacy default index.");
|
||||
VERIFY_ARE_EQUAL(legacyAttribute, textAttribute.GetLegacyAttributes());
|
||||
|
||||
Log::Comment(L"Foreground and background legacy defaults should map to default text colors.");
|
||||
legacyAttribute = fgLegacyDefault | bgLegacyDefault;
|
||||
textAttribute.SetDefaultForeground();
|
||||
textAttribute.SetDefaultBackground();
|
||||
VERIFY_ARE_EQUAL(textAttribute, TextAttribute{ legacyAttribute });
|
||||
|
||||
Log::Comment(L"Default foreground and background text colors should map back to legacy defaults.");
|
||||
VERIFY_ARE_EQUAL(legacyAttribute, textAttribute.GetLegacyAttributes());
|
||||
|
||||
// Reset the legacy default colors to white on black.
|
||||
TextAttribute::SetLegacyDefaultAttributes(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
}
|
||||
|
||||
@@ -142,12 +142,12 @@
|
||||
<!-- **END VC LIBS HACK** -->
|
||||
|
||||
<!-- This is required to get the package dependency in the AppXManifest. -->
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.4.2-prerelease.200604001\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.4.2-prerelease.200604001\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.4.2-prerelease.200604001\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.4.2-prerelease.200604001\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
</Target>
|
||||
|
||||
<Import Project="$(SolutionDir)build\rules\CollectWildcardResources.targets" />
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace TerminalAppLocalTests
|
||||
const auto commands1Json = VerifyParseSucceeded(commands1String);
|
||||
const auto commands2Json = VerifyParseSucceeded(commands2String);
|
||||
|
||||
std::unordered_map<winrt::hstring, Command> commands;
|
||||
std::map<winrt::hstring, Command> commands;
|
||||
VERIFY_ARE_EQUAL(0u, commands.size());
|
||||
{
|
||||
auto warnings = implementation::Command::LayerJson(commands, commands0Json);
|
||||
@@ -95,7 +95,7 @@ namespace TerminalAppLocalTests
|
||||
const auto commands2Json = VerifyParseSucceeded(commands2String);
|
||||
const auto commands3Json = VerifyParseSucceeded(commands3String);
|
||||
|
||||
std::unordered_map<winrt::hstring, Command> commands;
|
||||
std::map<winrt::hstring, Command> commands;
|
||||
VERIFY_ARE_EQUAL(0u, commands.size());
|
||||
{
|
||||
auto warnings = implementation::Command::LayerJson(commands, commands0Json);
|
||||
@@ -155,7 +155,7 @@ namespace TerminalAppLocalTests
|
||||
|
||||
const auto commands0Json = VerifyParseSucceeded(commands0String);
|
||||
|
||||
std::unordered_map<winrt::hstring, Command> commands;
|
||||
std::map<winrt::hstring, Command> commands;
|
||||
VERIFY_ARE_EQUAL(0u, commands.size());
|
||||
auto warnings = implementation::Command::LayerJson(commands, commands0Json);
|
||||
VERIFY_ARE_EQUAL(0u, warnings.size());
|
||||
@@ -239,7 +239,7 @@ namespace TerminalAppLocalTests
|
||||
const std::string commands0String{ R"([ { "name": { "key": "DuplicateTabCommandKey"}, "command": "copy" } ])" };
|
||||
const auto commands0Json = VerifyParseSucceeded(commands0String);
|
||||
|
||||
std::unordered_map<winrt::hstring, Command> commands;
|
||||
std::map<winrt::hstring, Command> commands;
|
||||
VERIFY_ARE_EQUAL(0u, commands.size());
|
||||
{
|
||||
auto warnings = implementation::Command::LayerJson(commands, commands0Json);
|
||||
@@ -279,7 +279,7 @@ namespace TerminalAppLocalTests
|
||||
|
||||
const auto commands0Json = VerifyParseSucceeded(commands0String);
|
||||
|
||||
std::unordered_map<winrt::hstring, Command> commands;
|
||||
std::map<winrt::hstring, Command> commands;
|
||||
VERIFY_ARE_EQUAL(0u, commands.size());
|
||||
auto warnings = implementation::Command::LayerJson(commands, commands0Json);
|
||||
VERIFY_ARE_EQUAL(0u, warnings.size());
|
||||
@@ -300,7 +300,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle());
|
||||
}
|
||||
{
|
||||
auto command = commands.at(L"Split pane, direction: vertical");
|
||||
auto command = commands.at(L"Split pane, direction: Vertical");
|
||||
VERIFY_IS_NOT_NULL(command);
|
||||
VERIFY_IS_NOT_NULL(command.Action());
|
||||
VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, command.Action().Action());
|
||||
@@ -310,7 +310,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Vertical, realArgs.SplitStyle());
|
||||
}
|
||||
{
|
||||
auto command = commands.at(L"Split pane, direction: horizontal");
|
||||
auto command = commands.at(L"Split pane, direction: Horizontal");
|
||||
VERIFY_IS_NOT_NULL(command);
|
||||
VERIFY_IS_NOT_NULL(command.Action());
|
||||
VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, command.Action().Action());
|
||||
@@ -329,7 +329,7 @@ namespace TerminalAppLocalTests
|
||||
|
||||
const auto commands0Json = VerifyParseSucceeded(commands0String);
|
||||
|
||||
std::unordered_map<winrt::hstring, Command> commands;
|
||||
std::map<winrt::hstring, Command> commands;
|
||||
VERIFY_ARE_EQUAL(0u, commands.size());
|
||||
auto warnings = implementation::Command::LayerJson(commands, commands0Json);
|
||||
VERIFY_ARE_EQUAL(0u, warnings.size());
|
||||
|
||||
@@ -115,11 +115,11 @@
|
||||
<!-- From Microsoft.UI.Xaml.targets -->
|
||||
<Native-Platform Condition="'$(Platform)' == 'Win32'">x86</Native-Platform>
|
||||
<Native-Platform Condition="'$(Platform)' != 'Win32'">$(Platform)</Native-Platform>
|
||||
<_MUXBinRoot>"$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\runtimes\win10-$(Native-Platform)\native\"</_MUXBinRoot>
|
||||
<_MUXBinRoot>"$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.4.2-prerelease.200604001\runtimes\win10-$(Native-Platform)\native\"</_MUXBinRoot>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- We actually can just straight up reference MUX here, it's fine -->
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.4.2-prerelease.200604001\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.4.2-prerelease.200604001\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Import Project="$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.4.2-prerelease.200604001\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.4.2-prerelease.200604001\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
|
||||
<Import Project="$(OpenConsoleDir)\src\common.build.post.props" />
|
||||
|
||||
|
||||
@@ -28,8 +28,8 @@ static constexpr std::string_view SplitPaneKey{ "splitPane" };
|
||||
static constexpr std::string_view ResizePaneKey{ "resizePane" };
|
||||
static constexpr std::string_view MoveFocusKey{ "moveFocus" };
|
||||
static constexpr std::string_view FindKey{ "find" };
|
||||
static constexpr std::string_view ToggleRetroEffectKey{ "toggleRetroEffect" };
|
||||
static constexpr std::string_view ToggleFullscreenKey{ "toggleFullscreen" };
|
||||
static constexpr std::string_view ExecuteCommandlineKey{ "wt" };
|
||||
static constexpr std::string_view SetTabColorKey{ "setTabColor" };
|
||||
static constexpr std::string_view OpenTabColorPickerKey{ "openTabColorPicker" };
|
||||
static constexpr std::string_view RenameTabKey{ "renameTab" };
|
||||
@@ -72,7 +72,6 @@ namespace winrt::TerminalApp::implementation
|
||||
{ ResizePaneKey, ShortcutAction::ResizePane },
|
||||
{ MoveFocusKey, ShortcutAction::MoveFocus },
|
||||
{ OpenSettingsKey, ShortcutAction::OpenSettings },
|
||||
{ ToggleRetroEffectKey, ShortcutAction::ToggleRetroEffect },
|
||||
{ ToggleFullscreenKey, ShortcutAction::ToggleFullscreen },
|
||||
{ SplitPaneKey, ShortcutAction::SplitPane },
|
||||
{ SetTabColorKey, ShortcutAction::SetTabColor },
|
||||
@@ -81,6 +80,7 @@ namespace winrt::TerminalApp::implementation
|
||||
{ FindKey, ShortcutAction::Find },
|
||||
{ RenameTabKey, ShortcutAction::RenameTab },
|
||||
{ ToggleCommandPaletteKey, ShortcutAction::ToggleCommandPalette },
|
||||
{ ExecuteCommandlineKey, ShortcutAction::ExecuteCommandline },
|
||||
};
|
||||
|
||||
using ParseResult = std::tuple<IActionArgs, std::vector<::TerminalApp::SettingsLoadWarnings>>;
|
||||
@@ -106,6 +106,8 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
{ ShortcutAction::SplitPane, winrt::TerminalApp::implementation::SplitPaneArgs::FromJson },
|
||||
|
||||
{ ShortcutAction::ExecuteCommandline, winrt::TerminalApp::implementation::ExecuteCommandlineArgs::FromJson },
|
||||
|
||||
{ ShortcutAction::OpenSettings, winrt::TerminalApp::implementation::OpenSettingsArgs::FromJson },
|
||||
|
||||
{ ShortcutAction::SetTabColor, winrt::TerminalApp::implementation::SetTabColorArgs::FromJson },
|
||||
@@ -251,10 +253,10 @@ namespace winrt::TerminalApp::implementation
|
||||
{ ShortcutAction::ResizePane, RS_(L"ResizePaneCommandKey") },
|
||||
{ ShortcutAction::MoveFocus, RS_(L"MoveFocusCommandKey") },
|
||||
{ ShortcutAction::OpenSettings, RS_(L"OpenSettingsCommandKey") },
|
||||
{ ShortcutAction::ToggleRetroEffect, RS_(L"ToggleRetroEffectCommandKey") },
|
||||
{ ShortcutAction::ToggleFullscreen, RS_(L"ToggleFullscreenCommandKey") },
|
||||
{ ShortcutAction::SplitPane, RS_(L"SplitPaneCommandKey") },
|
||||
{ ShortcutAction::Invalid, L"" },
|
||||
{ ShortcutAction::ExecuteCommandline, L"" },
|
||||
{ ShortcutAction::Find, RS_(L"FindCommandKey") },
|
||||
{ ShortcutAction::SetTabColor, RS_(L"ResetTabColorCommandKey") },
|
||||
{ ShortcutAction::OpenTabColorPicker, RS_(L"OpenTabColorPickerCommandKey") },
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "MoveFocusArgs.g.cpp"
|
||||
#include "AdjustFontSizeArgs.g.cpp"
|
||||
#include "SplitPaneArgs.g.cpp"
|
||||
#include "ExecuteCommandlineArgs.g.cpp"
|
||||
#include "OpenSettingsArgs.g.cpp"
|
||||
#include "SetTabColorArgs.g.cpp"
|
||||
#include "RenameTabArgs.g.cpp"
|
||||
@@ -228,6 +229,14 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
winrt::hstring ExecuteCommandlineArgs::GenerateName() const
|
||||
{
|
||||
return winrt::hstring{
|
||||
fmt::format(std::wstring_view(RS_(L"ExecuteCommandlineCommandKey")),
|
||||
_Commandline)
|
||||
};
|
||||
}
|
||||
|
||||
winrt::hstring SetTabColorArgs::GenerateName() const
|
||||
{
|
||||
// "Set tab color to #RRGGBB"
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "MoveFocusArgs.g.h"
|
||||
#include "AdjustFontSizeArgs.g.h"
|
||||
#include "SplitPaneArgs.g.h"
|
||||
#include "ExecuteCommandlineArgs.g.h"
|
||||
#include "OpenSettingsArgs.g.h"
|
||||
#include "SetTabColorArgs.g.h"
|
||||
#include "RenameTabArgs.g.h"
|
||||
@@ -403,6 +404,37 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
};
|
||||
|
||||
struct ExecuteCommandlineArgs : public ExecuteCommandlineArgsT<ExecuteCommandlineArgs>
|
||||
{
|
||||
ExecuteCommandlineArgs() = default;
|
||||
GETSET_PROPERTY(winrt::hstring, Commandline, false);
|
||||
|
||||
static constexpr std::string_view CommandlineKey{ "commandline" };
|
||||
|
||||
public:
|
||||
hstring GenerateName() const;
|
||||
|
||||
bool Equals(const IActionArgs& other)
|
||||
{
|
||||
auto otherAsUs = other.try_as<ExecuteCommandlineArgs>();
|
||||
if (otherAsUs)
|
||||
{
|
||||
return otherAsUs->_Commandline == _Commandline;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
static FromJsonResult FromJson(const Json::Value& json)
|
||||
{
|
||||
// LOAD BEARING: Not using make_self here _will_ break you in the future!
|
||||
auto args = winrt::make_self<ExecuteCommandlineArgs>();
|
||||
if (auto commandline{ json[JsonKey(CommandlineKey)] })
|
||||
{
|
||||
args->_Commandline = winrt::to_hstring(commandline.asString());
|
||||
}
|
||||
return { *args, {} };
|
||||
}
|
||||
};
|
||||
|
||||
// Possible SettingsTarget values
|
||||
// TODO:GH#2550/#3475 - move these to a centralized deserializing place
|
||||
static constexpr std::string_view SettingsFileString{ "settingsFile" };
|
||||
|
||||
@@ -101,6 +101,11 @@ namespace TerminalApp
|
||||
SplitType SplitMode { get; };
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass ExecuteCommandlineArgs : IActionArgs
|
||||
{
|
||||
String Commandline;
|
||||
}
|
||||
|
||||
[default_interface] runtimeclass OpenSettingsArgs : IActionArgs
|
||||
{
|
||||
SettingsTarget Target { get; };
|
||||
|
||||
@@ -26,11 +26,6 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
Initialize();
|
||||
|
||||
// Disable XAML's automatic backplating of text when in High Contrast
|
||||
// mode: we want full control of and responsibility for the foreground
|
||||
// and background colors that we draw in XAML.
|
||||
HighContrastAdjustment(::winrt::Windows::UI::Xaml::ApplicationHighContrastAdjustment::None);
|
||||
}
|
||||
|
||||
AppLogic App::Logic()
|
||||
|
||||
@@ -231,14 +231,6 @@ namespace winrt::TerminalApp::implementation
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleToggleRetroEffect(const IInspectable& /*sender*/,
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
const auto termControl = _GetActiveControl();
|
||||
termControl.ToggleRetroEffect();
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleToggleFullscreen(const IInspectable& /*sender*/,
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
@@ -320,4 +312,40 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleExecuteCommandline(const IInspectable& /*sender*/,
|
||||
const TerminalApp::ActionEventArgs& actionArgs)
|
||||
{
|
||||
if (const auto& realArgs = actionArgs.ActionArgs().try_as<TerminalApp::ExecuteCommandlineArgs>())
|
||||
{
|
||||
// Convert the commandline into an array of args with
|
||||
// CommandLineToArgvW, similar to how the app typically does when
|
||||
// called from the commandline.
|
||||
int argc = 0;
|
||||
wil::unique_any<LPWSTR*, decltype(&::LocalFree), ::LocalFree> argv{ CommandLineToArgvW(realArgs.Commandline().c_str(), &argc) };
|
||||
if (argv)
|
||||
{
|
||||
std::vector<winrt::hstring> args;
|
||||
|
||||
// Make sure the first argument is wt.exe, because ParseArgs
|
||||
// will always skip the program name.
|
||||
args.emplace_back(L"wt.exe");
|
||||
for (auto& elem : wil::make_range(argv.get(), argc))
|
||||
{
|
||||
args.emplace_back(elem);
|
||||
}
|
||||
winrt::array_view<const winrt::hstring> argsView{ args };
|
||||
|
||||
::TerminalApp::AppCommandlineArgs appArgs;
|
||||
bool handled = appArgs.ParseArgs(argsView) == 0;
|
||||
if (handled)
|
||||
{
|
||||
_startupActions = appArgs.GetStartupActions();
|
||||
_ProcessStartupActions(false);
|
||||
}
|
||||
|
||||
actionArgs.Handled(handled);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -637,3 +637,52 @@ std::optional<winrt::TerminalApp::LaunchMode> AppCommandlineArgs::GetLaunchMode(
|
||||
{
|
||||
return _launchMode;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Attempts to parse an array of commandline args into a list of
|
||||
// commands to execute, and then parses these commands. As commands are
|
||||
// successfully parsed, they will generate ShortcutActions for us to be
|
||||
// able to execute. If we fail to parse any commands, we'll return the
|
||||
// error code from the failure to parse that command, and stop processing
|
||||
// additional commands.
|
||||
// - The first arg in args should be the program name "wt" (or some variant). It
|
||||
// will be ignored during parsing.
|
||||
// Arguments:
|
||||
// - args: an array of strings to process as a commandline. These args can contain spaces
|
||||
// Return Value:
|
||||
// - 0 if the commandline was successfully parsed
|
||||
int AppCommandlineArgs::ParseArgs(winrt::array_view<const winrt::hstring>& args)
|
||||
{
|
||||
auto commands = ::TerminalApp::AppCommandlineArgs::BuildCommands(args);
|
||||
|
||||
for (auto& cmdBlob : commands)
|
||||
{
|
||||
// On one hand, it seems like we should be able to have one
|
||||
// AppCommandlineArgs for parsing all of them, and collect the
|
||||
// results one at a time.
|
||||
//
|
||||
// On the other hand, re-using a CLI::App seems to leave state from
|
||||
// previous parsings around, so we could get mysterious behavior
|
||||
// where one command affects the values of the next.
|
||||
//
|
||||
// From https://cliutils.github.io/CLI11/book/chapters/options.html:
|
||||
// > If that option is not given, CLI11 will not touch the initial
|
||||
// > value. This allows you to set up defaults by simply setting
|
||||
// > your value beforehand.
|
||||
//
|
||||
// So we pretty much need the to either manually reset the state
|
||||
// each command, or build new ones.
|
||||
const auto result = ParseCommand(cmdBlob);
|
||||
|
||||
// If this succeeded, result will be 0. Otherwise, the caller should
|
||||
// exit(result), to exit the program.
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// If all the args were successfully parsed, we'll have some commands
|
||||
// built in _appArgs, which we'll use when the application starts up.
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,9 @@ public:
|
||||
|
||||
AppCommandlineArgs();
|
||||
~AppCommandlineArgs() = default;
|
||||
|
||||
int ParseCommand(const Commandline& command);
|
||||
int ParseArgs(winrt::array_view<const winrt::hstring>& args);
|
||||
|
||||
static std::vector<Commandline> BuildCommands(const std::vector<const wchar_t*>& args);
|
||||
static std::vector<Commandline> BuildCommands(winrt::array_view<const winrt::hstring>& args);
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
using namespace winrt::Windows::ApplicationModel;
|
||||
using namespace winrt::Windows::ApplicationModel::DataTransfer;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Xaml::Controls;
|
||||
using namespace winrt::Windows::UI::Core;
|
||||
using namespace winrt::Windows::System;
|
||||
using namespace winrt::Microsoft::Terminal;
|
||||
@@ -232,7 +231,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// this as a MTA, before the app is Create()'d
|
||||
WINRT_ASSERT(_loadedInitialSettings);
|
||||
|
||||
_root->DialogPresenter(*this);
|
||||
_root->ShowDialog({ this, &AppLogic::_ShowDialog });
|
||||
|
||||
// In UWP mode, we cannot handle taking over the title bar for tabs,
|
||||
// so this setting is overridden to false no matter what the preference is.
|
||||
@@ -278,10 +277,9 @@ namespace winrt::TerminalApp::implementation
|
||||
// - Only one dialog can be visible at a time. If another dialog is visible
|
||||
// when this is called, nothing happens.
|
||||
// Arguments:
|
||||
// - dialog: the dialog object that is going to show up
|
||||
// Return value:
|
||||
// - an IAsyncOperation with the dialog result
|
||||
winrt::Windows::Foundation::IAsyncOperation<ContentDialogResult> AppLogic::ShowDialog(winrt::Windows::UI::Xaml::Controls::ContentDialog dialog)
|
||||
// sender: unused
|
||||
// dialog: the dialog object that is going to show up
|
||||
fire_and_forget AppLogic::_ShowDialog(const winrt::Windows::Foundation::IInspectable& sender, winrt::Windows::UI::Xaml::Controls::ContentDialog dialog)
|
||||
{
|
||||
// DON'T release this lock in a wil::scope_exit. The scope_exit will get
|
||||
// called when we await, which is not what we want.
|
||||
@@ -289,7 +287,7 @@ namespace winrt::TerminalApp::implementation
|
||||
if (!lock)
|
||||
{
|
||||
// Another dialog is visible.
|
||||
co_return ContentDialogResult::None;
|
||||
return;
|
||||
}
|
||||
|
||||
// IMPORTANT: This is necessary as documented in the ContentDialog MSDN docs.
|
||||
@@ -323,7 +321,7 @@ namespace winrt::TerminalApp::implementation
|
||||
auto loadedRevoker{ dialog.Loaded(winrt::auto_revoke, themingLambda) }; // if it's not yet in the tree
|
||||
|
||||
// Display the dialog.
|
||||
co_return co_await dialog.ShowAsync(Controls::ContentDialogPlacement::Popup);
|
||||
co_await dialog.ShowAsync(Controls::ContentDialogPlacement::Popup);
|
||||
|
||||
// After the dialog is dismissed, the dialog lock (held by `lock`) will
|
||||
// be released so another can be shown
|
||||
@@ -335,7 +333,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// as the title and first content of the dialog, then also displays a
|
||||
// message for whatever exception was found while validating the settings.
|
||||
// - Only one dialog can be visible at a time. If another dialog is visible
|
||||
// when this is called, nothing happens. See ShowDialog for details
|
||||
// when this is called, nothing happens. See _ShowDialog for details
|
||||
// Arguments:
|
||||
// - titleKey: The key to use to lookup the title text from our resources.
|
||||
// - contentKey: The key to use to lookup the content text from our resources.
|
||||
@@ -380,7 +378,7 @@ namespace winrt::TerminalApp::implementation
|
||||
dialog.CloseButtonText(buttonText);
|
||||
dialog.DefaultButton(Controls::ContentDialogButton::Close);
|
||||
|
||||
ShowDialog(dialog);
|
||||
_ShowDialog(nullptr, dialog);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -388,7 +386,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// settings. Displays messages for whatever warnings were found while
|
||||
// validating the settings.
|
||||
// - Only one dialog can be visible at a time. If another dialog is visible
|
||||
// when this is called, nothing happens. See ShowDialog for details
|
||||
// when this is called, nothing happens. See _ShowDialog for details
|
||||
void AppLogic::_ShowLoadWarningsDialog()
|
||||
{
|
||||
auto title = RS_(L"SettingsValidateErrorTitle");
|
||||
@@ -439,7 +437,7 @@ namespace winrt::TerminalApp::implementation
|
||||
dialog.CloseButtonText(buttonText);
|
||||
dialog.DefaultButton(Controls::ContentDialogButton::Close);
|
||||
|
||||
ShowDialog(dialog);
|
||||
_ShowDialog(nullptr, dialog);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -474,7 +472,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - a point containing the requested dimensions in pixels.
|
||||
winrt::Windows::Foundation::Point AppLogic::GetLaunchDimensions(uint32_t dpi)
|
||||
winrt::Windows::Foundation::Size AppLogic::GetLaunchDimensions(uint32_t dpi)
|
||||
{
|
||||
if (!_loadedInitialSettings)
|
||||
{
|
||||
@@ -504,7 +502,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// of the height calculation here.
|
||||
auto titlebar = TitlebarControl{ static_cast<uint64_t>(0) };
|
||||
titlebar.Measure({ SHRT_MAX, SHRT_MAX });
|
||||
proposedSize.Y += (titlebar.DesiredSize().Height) * scale;
|
||||
proposedSize.Height += (titlebar.DesiredSize().Height) * scale;
|
||||
}
|
||||
else if (_settings->GlobalSettings().AlwaysShowTabs())
|
||||
{
|
||||
@@ -519,7 +517,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// For whatever reason, there's about 6px of unaccounted-for space
|
||||
// in the application. I couldn't tell you where these 6px are
|
||||
// coming from, but they need to be included in this math.
|
||||
proposedSize.Y += (tabControl.DesiredSize().Height + 6) * scale;
|
||||
proposedSize.Width += (tabControl.DesiredSize().Height + 6) * scale;
|
||||
}
|
||||
|
||||
return proposedSize;
|
||||
@@ -974,7 +972,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// or 0. (see AppLogic::_ParseArgs)
|
||||
int32_t AppLogic::SetStartupCommandline(array_view<const winrt::hstring> args)
|
||||
{
|
||||
const auto result = _ParseArgs(args);
|
||||
const auto result = _appArgs.ParseArgs(args);
|
||||
if (result == 0)
|
||||
{
|
||||
_appArgs.ValidateStartupCommands();
|
||||
@@ -984,53 +982,6 @@ namespace winrt::TerminalApp::implementation
|
||||
return result;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Attempts to parse an array of commandline args into a list of
|
||||
// commands to execute, and then parses these commands. As commands are
|
||||
// successfully parsed, they will generate ShortcutActions for us to be
|
||||
// able to execute. If we fail to parse any commands, we'll return the
|
||||
// error code from the failure to parse that command, and stop processing
|
||||
// additional commands.
|
||||
// Arguments:
|
||||
// - args: an array of strings to process as a commandline. These args can contain spaces
|
||||
// Return Value:
|
||||
// - 0 if the commandline was successfully parsed
|
||||
int AppLogic::_ParseArgs(winrt::array_view<const hstring>& args)
|
||||
{
|
||||
auto commands = ::TerminalApp::AppCommandlineArgs::BuildCommands(args);
|
||||
|
||||
for (auto& cmdBlob : commands)
|
||||
{
|
||||
// On one hand, it seems like we should be able to have one
|
||||
// AppCommandlineArgs for parsing all of them, and collect the
|
||||
// results one at a time.
|
||||
//
|
||||
// On the other hand, re-using a CLI::App seems to leave state from
|
||||
// previous parsings around, so we could get mysterious behavior
|
||||
// where one command affects the values of the next.
|
||||
//
|
||||
// From https://cliutils.github.io/CLI11/book/chapters/options.html:
|
||||
// > If that option is not given, CLI11 will not touch the initial
|
||||
// > value. This allows you to set up defaults by simply setting
|
||||
// > your value beforehand.
|
||||
//
|
||||
// So we pretty much need the to either manually reset the state
|
||||
// each command, or build new ones.
|
||||
const auto result = _appArgs.ParseCommand(cmdBlob);
|
||||
|
||||
// If this succeeded, result will be 0. Otherwise, the caller should
|
||||
// exit(result), to exit the program.
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// If all the args were successfully parsed, we'll have some commands
|
||||
// built in _appArgs, which we'll use when the application starts up.
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - If there were any errors parsing the commandline that was used to
|
||||
// initialize the terminal, this will return a string containing that
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace winrt::TerminalApp::implementation
|
||||
winrt::hstring ApplicationDisplayName() const;
|
||||
winrt::hstring ApplicationVersion() const;
|
||||
|
||||
Windows::Foundation::Point GetLaunchDimensions(uint32_t dpi);
|
||||
Windows::Foundation::Size GetLaunchDimensions(uint32_t dpi);
|
||||
winrt::Windows::Foundation::Point GetLaunchInitialPositions(int32_t defaultInitialX, int32_t defaultInitialY);
|
||||
winrt::Windows::UI::Xaml::ElementTheme GetRequestedTheme();
|
||||
LaunchMode GetLaunchMode();
|
||||
@@ -49,8 +49,6 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void WindowCloseButtonClicked();
|
||||
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> ShowDialog(winrt::Windows::UI::Xaml::Controls::ContentDialog dialog);
|
||||
|
||||
// -------------------------------- WinRT Events ---------------------------------
|
||||
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(RequestedThemeChanged, _requestedThemeChangedHandlers, winrt::Windows::Foundation::IInspectable, winrt::Windows::UI::Xaml::ElementTheme);
|
||||
|
||||
@@ -81,6 +79,7 @@ namespace winrt::TerminalApp::implementation
|
||||
::TerminalApp::AppCommandlineArgs _appArgs;
|
||||
int _ParseArgs(winrt::array_view<const hstring>& args);
|
||||
|
||||
fire_and_forget _ShowDialog(const winrt::Windows::Foundation::IInspectable& sender, winrt::Windows::UI::Xaml::Controls::ContentDialog dialog);
|
||||
void _ShowLoadErrorsDialog(const winrt::hstring& titleKey, const winrt::hstring& contentKey, HRESULT settingsLoadedResult);
|
||||
void _ShowLoadWarningsDialog();
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace TerminalApp
|
||||
FullscreenMode,
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass AppLogic : IDirectKeyListener, IDialogPresenter
|
||||
[default_interface] runtimeclass AppLogic : IDirectKeyListener
|
||||
{
|
||||
AppLogic();
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace TerminalApp
|
||||
String ApplicationDisplayName { get; };
|
||||
String ApplicationVersion { get; };
|
||||
|
||||
Windows.Foundation.Point GetLaunchDimensions(UInt32 dpi);
|
||||
Windows.Foundation.Size GetLaunchDimensions(UInt32 dpi);
|
||||
Windows.Foundation.Point GetLaunchInitialPositions(Int32 defaultInitialX, Int32 defaultInitialY);
|
||||
Windows.UI.Xaml.ElementTheme GetRequestedTheme();
|
||||
LaunchMode GetLaunchMode();
|
||||
@@ -50,10 +50,6 @@ namespace TerminalApp
|
||||
void TitlebarClicked();
|
||||
void WindowCloseButtonClicked();
|
||||
|
||||
// See IDialogPresenter and TerminalPage's DialogPresenter for more
|
||||
// information.
|
||||
Windows.Foundation.IAsyncOperation<Windows.UI.Xaml.Controls.ContentDialogResult> ShowDialog(Windows.UI.Xaml.Controls.ContentDialog dialog);
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<Object, Windows.UI.Xaml.UIElement> SetTitleBarContent;
|
||||
event Windows.Foundation.TypedEventHandler<Object, String> TitleChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, LastTabClosedEventArgs> LastTabClosed;
|
||||
|
||||
@@ -718,30 +718,3 @@ std::string CascadiaSettings::_ApplyFirstRunChangesToSettingsTemplate(std::strin
|
||||
|
||||
return finalSettings;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Lookup the color scheme for a given profile. If the profile doesn't exist,
|
||||
// or the scheme name listed in the profile doesn't correspond to a scheme,
|
||||
// this will return `nullptr`.
|
||||
// Arguments:
|
||||
// - profileGuid: the GUID of the profile to find the scheme for.
|
||||
// Return Value:
|
||||
// - a non-owning pointer to the scheme.
|
||||
const ColorScheme* CascadiaSettings::GetColorSchemeForProfile(const GUID profileGuid) const
|
||||
{
|
||||
auto* profile = FindProfile(profileGuid);
|
||||
if (!profile)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
auto schemeName = profile->GetSchemeName().has_value() ? profile->GetSchemeName().value() : L"\0";
|
||||
auto scheme = _globals.GetColorSchemes().find(schemeName);
|
||||
if (scheme != _globals.GetColorSchemes().end())
|
||||
{
|
||||
return &scheme->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +70,6 @@ public:
|
||||
static std::filesystem::path GetDefaultSettingsPath();
|
||||
|
||||
const Profile* FindProfile(GUID profileGuid) const noexcept;
|
||||
const ColorScheme* GetColorSchemeForProfile(const GUID profileGuid) const;
|
||||
|
||||
std::vector<TerminalApp::SettingsLoadWarnings>& GetWarnings();
|
||||
|
||||
|
||||
@@ -24,82 +24,82 @@
|
||||
<Setter Property="Margin" Value="2"/>
|
||||
</Style>
|
||||
</VariableSizedWrapGrid.Resources>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="Crimson" x:Uid="CrimsonColorButton">
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="Crimson">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="Crimson"/>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="SteelBlue" x:Uid="SteelBlueColorButton">
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="SteelBlue">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="SteelBlue"/>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="MediumSeaGreen" x:Uid="MediumSeaGreenColorButton">
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="MediumSeaGreen">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="MediumSeaGreen"/>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="DarkOrange" x:Uid="DarkOrangeColorButton">
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="DarkOrange">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="DarkOrange"/>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="MediumVioletRed" x:Uid="MediumVioletRedColorButton">
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="MediumVioletRed">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="MediumVioletRed"/>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="DodgerBlue" x:Uid="DodgerBlueColorButton">
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="DodgerBlue">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="DodgerBlue"/>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="LimeGreen" x:Uid="LimeGreenColorButton">
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="LimeGreen">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="LimeGreen"/>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="Yellow" x:Uid="YellowColorButton">
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="Yellow">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="Yellow"/>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="BlueViolet" x:Uid="BlueVioletColorButton">
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="BlueViolet">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="BlueViolet"/>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="SlateBlue" x:Uid="SlateBlueColorButton">
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="SlateBlue">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="SlateBlue"/>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="Lime" x:Uid="LimeColorButton">
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="Lime">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="Lime"/>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="Tan" x:Uid="TanColorButton">
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="Tan">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="Tan"/>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="Magenta" x:Uid="MagentaColorButton">
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="Magenta">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="Magenta"/>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="Cyan" x:Uid="CyanColorButton">
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="Cyan">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="Cyan"/>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="SkyBlue" x:Uid="SkyBlueColorButton">
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="SkyBlue">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="SkyBlue"/>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="DarkGray" x:Uid="DarkGrayColorButton">
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="DarkGray">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="DarkGray"/>
|
||||
</Button.Content>
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
#include "pch.h"
|
||||
#include "CommandKeyChordVisibilityConverter.h"
|
||||
#include "CommandKeyChordVisibilityConverter.g.cpp"
|
||||
|
||||
using namespace winrt::Windows;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
// Method Description:
|
||||
// - Attempt to convert something into another type. For the
|
||||
// CommandKeyChordVisibilityConverter, we're gonna check if `value` is a
|
||||
// string, and try and convert it into a Visibility value. If the input
|
||||
// param wasn't a string, or was the empty string, we'll return
|
||||
// Visibility::Collapsed. Otherwise, we'll return Visible.
|
||||
|
||||
// Arguments:
|
||||
// - value: the input object to attempt to convert into a Visibility.
|
||||
// Return Value:
|
||||
// - Visible if the object was a string and wasn't the empty string.
|
||||
Foundation::IInspectable CommandKeyChordVisibilityConverter::Convert(Foundation::IInspectable const& value,
|
||||
Windows::UI::Xaml::Interop::TypeName const& /* targetType */,
|
||||
Foundation::IInspectable const& /* parameter */,
|
||||
hstring const& /* language */)
|
||||
{
|
||||
const auto& name = winrt::unbox_value_or<hstring>(value, L"");
|
||||
return winrt::box_value(name.empty() ? Visibility::Collapsed : Visibility::Visible);
|
||||
}
|
||||
|
||||
// unused for one-way bindings
|
||||
Foundation::IInspectable CommandKeyChordVisibilityConverter::ConvertBack(Foundation::IInspectable const& /* value */,
|
||||
Windows::UI::Xaml::Interop::TypeName const& /* targetType */,
|
||||
Foundation::IInspectable const& /* parameter */,
|
||||
hstring const& /* language */)
|
||||
{
|
||||
throw hresult_not_implemented();
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "CommandKeyChordVisibilityConverter.g.h"
|
||||
#include "..\inc\cppwinrt_utils.h"
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct CommandKeyChordVisibilityConverter : CommandKeyChordVisibilityConverterT<CommandKeyChordVisibilityConverter>
|
||||
{
|
||||
CommandKeyChordVisibilityConverter() = default;
|
||||
|
||||
Windows::Foundation::IInspectable Convert(Windows::Foundation::IInspectable const& value,
|
||||
Windows::UI::Xaml::Interop::TypeName const& targetType,
|
||||
Windows::Foundation::IInspectable const& parameter,
|
||||
hstring const& language);
|
||||
|
||||
Windows::Foundation::IInspectable ConvertBack(Windows::Foundation::IInspectable const& value,
|
||||
Windows::UI::Xaml::Interop::TypeName const& targetType,
|
||||
Windows::Foundation::IInspectable const& parameter,
|
||||
hstring const& language);
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::TerminalApp::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(CommandKeyChordVisibilityConverter);
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace TerminalApp
|
||||
{
|
||||
// See https://docs.microsoft.com/en-us/windows/uwp/data-binding/data-binding-quickstart
|
||||
|
||||
// We use the default attribute to declare IValueConverter as the default
|
||||
// interface. In the listing, CommandKeyChordVisibilityConverter has only a
|
||||
// constructor, and no methods, so no default interface is generated for it.
|
||||
// The default attribute is optimal if you won't be adding instance members
|
||||
// to CommandKeyChordVisibilityConverter, because no QueryInterface will be
|
||||
// required to call the IValueConverter methods
|
||||
runtimeclass CommandKeyChordVisibilityConverter : [default] Windows.UI.Xaml.Data.IValueConverter
|
||||
{
|
||||
CommandKeyChordVisibilityConverter();
|
||||
};
|
||||
|
||||
}
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
#include "pch.h"
|
||||
#include "CommandPalette.h"
|
||||
#include "ActionArgs.h"
|
||||
#include "ActionAndArgs.h"
|
||||
|
||||
#include "CommandPalette.g.cpp"
|
||||
#include <winrt/Microsoft.Terminal.Settings.h>
|
||||
@@ -41,19 +43,11 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
_searchBox().Focus(FocusState::Programmatic);
|
||||
_filteredActionsView().SelectedIndex(0);
|
||||
|
||||
TraceLoggingWrite(
|
||||
g_hTerminalAppProvider, // handle to TerminalApp tracelogging provider
|
||||
"CommandPaletteOpened",
|
||||
TraceLoggingDescription("Event emitted when the Command Palette is opened"),
|
||||
TraceLoggingWideString(L"Action", "Mode", "which mode the palette was opened in"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Raise an event to return control to the Terminal.
|
||||
_dismissPalette();
|
||||
_close();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -105,11 +99,17 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
else if (key == VirtualKey::Enter)
|
||||
{
|
||||
// Action Mode: Dispatch the action of the selected command.
|
||||
|
||||
if (const auto selectedItem = _filteredActionsView().SelectedItem())
|
||||
if (_mode == PaletteMode::ActionMode)
|
||||
{
|
||||
_dispatchCommand(selectedItem.try_as<Command>());
|
||||
// Action Mode: Dispatch the action of the selected command.
|
||||
if (const auto selectedItem = _filteredActionsView().SelectedItem())
|
||||
{
|
||||
_dispatchAction();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_dispatchCommandline();
|
||||
}
|
||||
|
||||
e.Handled(true);
|
||||
@@ -119,7 +119,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// Action Mode: Dismiss the palette if the text is empty, otherwise clear the search string.
|
||||
if (_searchBox().Text().empty())
|
||||
{
|
||||
_dismissPalette();
|
||||
_close();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -141,7 +141,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void CommandPalette::_rootPointerPressed(Windows::Foundation::IInspectable const& /*sender*/,
|
||||
Windows::UI::Xaml::Input::PointerRoutedEventArgs const& /*e*/)
|
||||
{
|
||||
_dismissPalette();
|
||||
_close();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -169,55 +169,14 @@ namespace winrt::TerminalApp::implementation
|
||||
void CommandPalette::_listItemClicked(Windows::Foundation::IInspectable const& /*sender*/,
|
||||
Windows::UI::Xaml::Controls::ItemClickEventArgs const& e)
|
||||
{
|
||||
_dispatchCommand(e.ClickedItem().try_as<TerminalApp::Command>());
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Helper method for retrieving the action from a command the user
|
||||
// selected, and dispatching that command. Also fires a tracelogging event
|
||||
// indicating that the user successfully found the action they were
|
||||
// looking for.
|
||||
// Arguments:
|
||||
// - command: the Command to dispatch. This might be null.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void CommandPalette::_dispatchCommand(const TerminalApp::Command& command)
|
||||
{
|
||||
if (command)
|
||||
if (auto command{ e.ClickedItem().try_as<TerminalApp::Command>() })
|
||||
{
|
||||
const auto actionAndArgs = command.Action();
|
||||
_dispatch.DoAction(actionAndArgs);
|
||||
_close();
|
||||
|
||||
TraceLoggingWrite(
|
||||
g_hTerminalAppProvider, // handle to TerminalApp tracelogging provider
|
||||
"CommandPaletteDispatchedAction",
|
||||
TraceLoggingDescription("Event emitted when the user selects an action in the Command Palette"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance));
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Helper method for closing the command palette, when the user has _not_
|
||||
// selected an action. Also fires a tracelogging event indicating that the
|
||||
// user closed the palette without running a command.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void CommandPalette::_dismissPalette()
|
||||
{
|
||||
_close();
|
||||
|
||||
TraceLoggingWrite(
|
||||
g_hTerminalAppProvider, // handle to TerminalApp tracelogging provider
|
||||
"CommandPaletteDismissed",
|
||||
TraceLoggingDescription("Event emitted when the user dismisses the Command Palette without selecting an action"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance));
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Event handler for when the text in the input box changes. In Action
|
||||
// Mode, we'll update the list of displayed commands, and select the first one.
|
||||
@@ -228,6 +187,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void CommandPalette::_filterTextChanged(IInspectable const& /*sender*/,
|
||||
Windows::UI::Xaml::RoutedEventArgs const& /*args*/)
|
||||
{
|
||||
_checkMode();
|
||||
_updateFilteredActions();
|
||||
_filteredActionsView().SelectedIndex(0);
|
||||
|
||||
@@ -281,6 +241,12 @@ namespace winrt::TerminalApp::implementation
|
||||
void CommandPalette::_updateFilteredActions()
|
||||
{
|
||||
_filteredActions.Clear();
|
||||
|
||||
if (_mode == PaletteMode::CommandlineMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto searchText = _searchBox().Text();
|
||||
const bool addAll = searchText.empty();
|
||||
|
||||
@@ -455,4 +421,60 @@ namespace winrt::TerminalApp::implementation
|
||||
_searchBox().Text(L"");
|
||||
}
|
||||
|
||||
void CommandPalette::_checkMode()
|
||||
{
|
||||
_mode = PaletteMode::ActionMode;
|
||||
|
||||
auto inputText = _searchBox().Text();
|
||||
if (inputText.size() > 0)
|
||||
{
|
||||
if (inputText[0] == L'>')
|
||||
{
|
||||
_mode = PaletteMode::CommandlineMode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CommandPalette::_dispatchAction()
|
||||
{
|
||||
// Action Mode: Dispatch the action of the selected command.
|
||||
|
||||
if (const auto selectedItem = _filteredActionsView().SelectedItem())
|
||||
{
|
||||
if (const auto data = selectedItem.try_as<Command>())
|
||||
{
|
||||
const auto actionAndArgs = data.Action();
|
||||
_dispatch.DoAction(actionAndArgs);
|
||||
_close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CommandPalette::_dispatchCommandline()
|
||||
{
|
||||
const auto inputText = _searchBox().Text();
|
||||
const std::wstring input{ _searchBox().Text() };
|
||||
const auto rawCmdline{ input.substr(1) };
|
||||
|
||||
// Trim leading whitespace
|
||||
const auto firstNonSpace = rawCmdline.find_first_not_of(L" ");
|
||||
if (firstNonSpace == std::wstring::npos)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
winrt::hstring cmdline{ rawCmdline.substr(firstNonSpace) };
|
||||
|
||||
// Build the NewTab action from the values we've parsed on the commandline.
|
||||
auto executeActionAndArgs = winrt::make_self<implementation::ActionAndArgs>();
|
||||
executeActionAndArgs->Action(ShortcutAction::ExecuteCommandline);
|
||||
auto args = winrt::make_self<implementation::ExecuteCommandlineArgs>();
|
||||
args->Commandline(cmdline);
|
||||
executeActionAndArgs->Args(*args);
|
||||
|
||||
if (_dispatch.DoAction(*executeActionAndArgs))
|
||||
{
|
||||
_close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
enum class PaletteMode : uint32_t
|
||||
{
|
||||
ActionMode = 0,
|
||||
CommandlineMode
|
||||
};
|
||||
|
||||
struct CommandPalette : CommandPaletteT<CommandPalette>
|
||||
{
|
||||
CommandPalette();
|
||||
@@ -24,6 +30,8 @@ namespace winrt::TerminalApp::implementation
|
||||
Windows::Foundation::Collections::IVector<TerminalApp::Command> _allActions{ nullptr };
|
||||
winrt::TerminalApp::ShortcutActionDispatch _dispatch;
|
||||
|
||||
PaletteMode _mode{ PaletteMode::ActionMode };
|
||||
|
||||
void _filterTextChanged(Windows::Foundation::IInspectable const& sender,
|
||||
Windows::UI::Xaml::RoutedEventArgs const& args);
|
||||
void _keyDownHandler(Windows::Foundation::IInspectable const& sender,
|
||||
@@ -36,13 +44,14 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void _selectNextItem(const bool moveDown);
|
||||
|
||||
void _checkMode();
|
||||
|
||||
void _updateFilteredActions();
|
||||
static int _getWeight(const winrt::hstring& searchText, const winrt::hstring& name);
|
||||
void _close();
|
||||
|
||||
void _dispatchCommand(const TerminalApp::Command& command);
|
||||
|
||||
void _dismissPalette();
|
||||
void _dispatchAction();
|
||||
void _dispatchCommandline();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -19,9 +19,6 @@ the MIT License. See LICENSE in the project root for license information. -->
|
||||
adds it conditionally -->
|
||||
<Windows10version1903:ThemeShadow x:Name="CommandPaletteShadow" />
|
||||
|
||||
<!-- This creates an instance of our CommandKeyChordVisibilityConverter we can reference below -->
|
||||
<local:CommandKeyChordVisibilityConverter x:Key="CommandKeyChordVisibilityConverter"/>
|
||||
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
<Style x:Key="CommandPaletteBackground" TargetType="Grid">
|
||||
@@ -179,14 +176,8 @@ the MIT License. See LICENSE in the project root for license information. -->
|
||||
HorizontalAlignment="Left"
|
||||
Text="{x:Bind Name, Mode=OneWay}" />
|
||||
|
||||
<!-- The block for the key chord is only visible
|
||||
when there's actual text set as the label. See
|
||||
CommandKeyChordVisibilityConverter for details. -->
|
||||
<Border
|
||||
Grid.Column="2"
|
||||
Visibility="{x:Bind KeyChordText,
|
||||
Mode=OneWay,
|
||||
Converter={StaticResource CommandKeyChordVisibilityConverter}}"
|
||||
BorderBrush="{ThemeResource SystemControlForegroundBaseMediumBrush}"
|
||||
Background="{ThemeResource SystemControlForegroundBaseLowBrush}"
|
||||
BorderThickness="1"
|
||||
|
||||
@@ -31,8 +31,6 @@ static constexpr std::string_view ShowTabsInTitlebarKey{ "showTabsInTitlebar" };
|
||||
static constexpr std::string_view WordDelimitersKey{ "wordDelimiters" };
|
||||
static constexpr std::string_view CopyOnSelectKey{ "copyOnSelect" };
|
||||
static constexpr std::string_view CopyFormattingKey{ "copyFormatting" };
|
||||
static constexpr std::string_view WarnAboutLargePasteKey{ "largePasteWarning" };
|
||||
static constexpr std::string_view WarnAboutMultiLinePasteKey{ "multiLinePasteWarning" };
|
||||
static constexpr std::string_view LaunchModeKey{ "launchMode" };
|
||||
static constexpr std::string_view ConfirmCloseAllKey{ "confirmCloseAllTabs" };
|
||||
static constexpr std::string_view SnapToGridOnResizeKey{ "snapToGridOnResize" };
|
||||
@@ -192,10 +190,6 @@ void GlobalAppSettings::LayerJson(const Json::Value& json)
|
||||
|
||||
JsonUtils::GetBool(json, CopyFormattingKey, _CopyFormatting);
|
||||
|
||||
JsonUtils::GetBool(json, WarnAboutLargePasteKey, _WarnAboutLargePaste);
|
||||
|
||||
JsonUtils::GetBool(json, WarnAboutMultiLinePasteKey, _WarnAboutMultiLinePaste);
|
||||
|
||||
if (auto launchMode{ json[JsonKey(LaunchModeKey)] })
|
||||
{
|
||||
_LaunchMode = _ParseLaunchMode(GetWstringFromJson(launchMode));
|
||||
|
||||
@@ -75,8 +75,6 @@ public:
|
||||
GETSET_PROPERTY(std::wstring, WordDelimiters); // default value set in constructor
|
||||
GETSET_PROPERTY(bool, CopyOnSelect, false);
|
||||
GETSET_PROPERTY(bool, CopyFormatting, false);
|
||||
GETSET_PROPERTY(bool, WarnAboutLargePaste, true);
|
||||
GETSET_PROPERTY(bool, WarnAboutMultiLinePaste, true);
|
||||
GETSET_PROPERTY(LaunchPosition, InitialPosition);
|
||||
GETSET_PROPERTY(winrt::TerminalApp::LaunchMode, LaunchMode, winrt::TerminalApp::LaunchMode::DefaultMode);
|
||||
GETSET_PROPERTY(bool, SnapToGridOnResize, true);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "CascadiaSettings.h"
|
||||
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::Graphics::Display;
|
||||
using namespace winrt::Windows::UI;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Core;
|
||||
@@ -921,6 +922,102 @@ bool Pane::CanSplit(SplitState splitType)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - This is a helper to determine if a given Pane can be split, but without
|
||||
// using the ActualWidth() and ActualHeight() methods. This is used during
|
||||
// processing of many "split-pane" commands, which could happen _before_ we've
|
||||
// laid out a Pane for the first time. When this happens, the Pane's don't
|
||||
// have an actual size yet. However, we'd still like to figure out if the pane
|
||||
// could be split, once they're all laid out.
|
||||
// - This method assumes that the Pane we're attempting to split is `target`,
|
||||
// and this method should be called on the root of a tree of Panes.
|
||||
// - We'll walk down the tree attempting to find `target`. As we traverse the
|
||||
// tree, we'll reduce the size passed to each subsequent recursive call. The
|
||||
// size passed to this method represents how much space this Pane _will_ have
|
||||
// to use.
|
||||
// * If this pane is a leaf, and it's the pane we're looking for, use the
|
||||
// available space to calculate which direction to split in.
|
||||
// * If this pane is _any other leaf_, then just return nullopt, to indicate
|
||||
// that the `target` Pane is not down this branch.
|
||||
// * If this pane is a parent, calculate how much space our children will be
|
||||
// able to use, and recurse into them.
|
||||
// Arguments:
|
||||
// - target: The Pane we're attempting to split.
|
||||
// - splitType: The direction we're attempting to split in.
|
||||
// - availableSpace: The theoretical space that's available for this pane to be able to split.
|
||||
// Return Value:
|
||||
// - nullopt if `target` is not this pane or a child of this pane, otherwise
|
||||
// true iff we could split this pane, given `availableSpace`
|
||||
// Note:
|
||||
// - This method is highly similar to Pane::PreCalculateAutoSplit
|
||||
std::optional<bool> Pane::PreCalculateCanSplit(const std::shared_ptr<Pane> target,
|
||||
SplitState splitType,
|
||||
const winrt::Windows::Foundation::Size availableSpace) const
|
||||
{
|
||||
if (_IsLeaf())
|
||||
{
|
||||
if (target.get() == this)
|
||||
{
|
||||
//If this pane is a leaf, and it's the pane we're looking for, use
|
||||
//the available space to calculate which direction to split in.
|
||||
const Size minSize = _GetMinSize();
|
||||
|
||||
if (splitType == SplitState::None)
|
||||
{
|
||||
return { false };
|
||||
}
|
||||
|
||||
if (splitType == SplitState::Vertical)
|
||||
{
|
||||
const auto widthMinusSeparator = availableSpace.Width - CombinedPaneBorderSize;
|
||||
const auto newWidth = widthMinusSeparator * Half;
|
||||
|
||||
return { newWidth > minSize.Width };
|
||||
}
|
||||
|
||||
if (splitType == SplitState::Horizontal)
|
||||
{
|
||||
const auto heightMinusSeparator = availableSpace.Height - CombinedPaneBorderSize;
|
||||
const auto newHeight = heightMinusSeparator * Half;
|
||||
|
||||
return { newHeight > minSize.Height };
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If this pane is _any other leaf_, then just return nullopt, to
|
||||
// indicate that the `target` Pane is not down this branch.
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If this pane is a parent, calculate how much space our children will
|
||||
// be able to use, and recurse into them.
|
||||
|
||||
const bool isVerticalSplit = _splitState == SplitState::Vertical;
|
||||
const float firstWidth = isVerticalSplit ?
|
||||
(availableSpace.Width * _desiredSplitPosition) - PaneBorderSize :
|
||||
availableSpace.Width;
|
||||
const float secondWidth = isVerticalSplit ?
|
||||
(availableSpace.Width - firstWidth) - PaneBorderSize :
|
||||
availableSpace.Width;
|
||||
const float firstHeight = !isVerticalSplit ?
|
||||
(availableSpace.Height * _desiredSplitPosition) - PaneBorderSize :
|
||||
availableSpace.Height;
|
||||
const float secondHeight = !isVerticalSplit ?
|
||||
(availableSpace.Height - firstHeight) - PaneBorderSize :
|
||||
availableSpace.Height;
|
||||
|
||||
const auto firstResult = _firstChild->PreCalculateCanSplit(target, splitType, { firstWidth, firstHeight });
|
||||
return firstResult.has_value() ? firstResult : _secondChild->PreCalculateCanSplit(target, splitType, { secondWidth, secondHeight });
|
||||
}
|
||||
|
||||
// We should not possibly be getting here - both the above branches should
|
||||
// return a value.
|
||||
FAIL_FAST();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Split the focused pane in our tree of panes, and place the given
|
||||
// TermControl into the newly created pane. If we're the focused pane, then
|
||||
|
||||
@@ -64,7 +64,9 @@ public:
|
||||
const winrt::Microsoft::Terminal::TerminalControl::TermControl& control);
|
||||
float CalcSnappedDimension(const bool widthOrHeight, const float dimension) const;
|
||||
std::optional<winrt::TerminalApp::SplitState> PreCalculateAutoSplit(const std::shared_ptr<Pane> target, const winrt::Windows::Foundation::Size parentSize) const;
|
||||
|
||||
std::optional<bool> PreCalculateCanSplit(const std::shared_ptr<Pane> target,
|
||||
winrt::TerminalApp::SplitState splitType,
|
||||
const winrt::Windows::Foundation::Size availableSpace) const;
|
||||
void Shutdown();
|
||||
void Close();
|
||||
|
||||
|
||||
@@ -551,7 +551,7 @@ void Profile::SetColorScheme(std::optional<std::wstring> schemeName) noexcept
|
||||
_schemeName = std::move(schemeName);
|
||||
}
|
||||
|
||||
const std::optional<std::wstring>& Profile::GetSchemeName() const noexcept
|
||||
std::optional<std::wstring>& Profile::GetSchemeName() noexcept
|
||||
{
|
||||
return _schemeName;
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ public:
|
||||
void SetGuid(GUID guid) noexcept { _guid = guid; }
|
||||
void SetFontFace(std::wstring fontFace) noexcept;
|
||||
void SetColorScheme(std::optional<std::wstring> schemeName) noexcept;
|
||||
const std::optional<std::wstring>& GetSchemeName() const noexcept;
|
||||
std::optional<std::wstring>& GetSchemeName() noexcept;
|
||||
void SetTabTitle(std::wstring tabTitle) noexcept;
|
||||
void SetSuppressApplicationTitle(bool suppressApplicationTitle) noexcept;
|
||||
void SetAcrylicOpacity(double opacity) noexcept;
|
||||
|
||||
@@ -347,30 +347,6 @@
|
||||
<value>Command Prompt</value>
|
||||
<comment>This is the name of "Command Prompt", as localized in Windows. The localization here should match the one in the Windows product for "Command Prompt"</comment>
|
||||
</data>
|
||||
<data name="LargePasteDialog.CloseButtonText" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
</data>
|
||||
<data name="LargePasteDialog.Content" xml:space="preserve">
|
||||
<value>You are about to paste text that is longer than 5 KiB. Do you wish to continue?</value>
|
||||
</data>
|
||||
<data name="LargePasteDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<value>Paste anyway</value>
|
||||
</data>
|
||||
<data name="LargePasteDialog.Title" xml:space="preserve">
|
||||
<value>Warning</value>
|
||||
</data>
|
||||
<data name="MultiLinePasteDialog.CloseButtonText" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
</data>
|
||||
<data name="MultiLinePasteDialog.Content" xml:space="preserve">
|
||||
<value>You are about to paste text that contains multiple lines. If you paste this text into your shell, it may result in the unexpected execution of commands. Do you wish to continue?</value>
|
||||
</data>
|
||||
<data name="MultiLinePasteDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<value>Paste anyway</value>
|
||||
</data>
|
||||
<data name="MultiLinePasteDialog.Title" xml:space="preserve">
|
||||
<value>Warning</value>
|
||||
</data>
|
||||
<data name="CommandPalette_SearchBox.PlaceholderText" xml:space="preserve">
|
||||
<value>Type a command name...</value>
|
||||
</data>
|
||||
@@ -501,12 +477,13 @@
|
||||
<data name="ResetFontSizeCommandKey" xml:space="preserve">
|
||||
<value>Reset font size</value>
|
||||
</data>
|
||||
<data name="ToggleRetroEffectCommandKey" xml:space="preserve">
|
||||
<value>Toggle retro terminal effect</value>
|
||||
</data>
|
||||
<data name="ToggleCommandPaletteCommandKey" xml:space="preserve">
|
||||
<value>Toggle command palette</value>
|
||||
</data>
|
||||
<data name="ExecuteCommandlineCommandKey" xml:space="preserve">
|
||||
<value>Run the commandline "{0}" in this window</value>
|
||||
<comment>{0} will be replaced with a user-provided commandline</comment>
|
||||
</data>
|
||||
<data name="SetTabColorCommandKey" xml:space="preserve">
|
||||
<value>Set tab color to {0}</value>
|
||||
<comment>{0} will be replaced with a color, displayed in hexadecimal (#RRGGBB) notation.</comment>
|
||||
@@ -524,52 +501,4 @@
|
||||
<data name="ResetTabNameCommandKey" xml:space="preserve">
|
||||
<value>Reset tab title</value>
|
||||
</data>
|
||||
<data name="CrimsonColorButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Crimson</value>
|
||||
</data>
|
||||
<data name="SteelBlueColorButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Steel Blue</value>
|
||||
</data>
|
||||
<data name="MediumSeaGreenColorButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Medium Sea Green</value>
|
||||
</data>
|
||||
<data name="DarkOrangeColorButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Dark Orange</value>
|
||||
</data>
|
||||
<data name="MediumVioletRedColorButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Medium Violet Red</value>
|
||||
</data>
|
||||
<data name="DodgerBlueColorButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Dodger Blue</value>
|
||||
</data>
|
||||
<data name="LimeGreenColorButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Lime Green</value>
|
||||
</data>
|
||||
<data name="YellowColorButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Yellow</value>
|
||||
</data>
|
||||
<data name="BlueVioletColorButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Blue Violet</value>
|
||||
</data>
|
||||
<data name="SlateBlueColorButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Slate Blue</value>
|
||||
</data>
|
||||
<data name="LimeColorButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Lime</value>
|
||||
</data>
|
||||
<data name="TanColorButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Tan</value>
|
||||
</data>
|
||||
<data name="MagentaColorButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Magenta</value>
|
||||
</data>
|
||||
<data name="CyanColorButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Cyan</value>
|
||||
</data>
|
||||
<data name="SkyBlueColorButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Sky Blue</value>
|
||||
</data>
|
||||
<data name="DarkGrayColorButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Dark Gray</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -154,11 +154,6 @@ namespace winrt::TerminalApp::implementation
|
||||
_ResetFontSizeHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::ToggleRetroEffect:
|
||||
{
|
||||
_ToggleRetroEffectHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::ToggleFullscreen:
|
||||
{
|
||||
_ToggleFullscreenHandlers(*this, *eventArgs);
|
||||
@@ -169,6 +164,10 @@ namespace winrt::TerminalApp::implementation
|
||||
_ToggleCommandPaletteHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::ExecuteCommandline:
|
||||
{
|
||||
_ExecuteCommandlineHandlers(*this, *eventArgs);
|
||||
}
|
||||
case ShortcutAction::SetTabColor:
|
||||
{
|
||||
_SetTabColorHandlers(*this, *eventArgs);
|
||||
|
||||
@@ -46,9 +46,9 @@ namespace winrt::TerminalApp::implementation
|
||||
TYPED_EVENT(ResizePane, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
|
||||
TYPED_EVENT(Find, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
|
||||
TYPED_EVENT(MoveFocus, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
|
||||
TYPED_EVENT(ToggleRetroEffect, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
|
||||
TYPED_EVENT(ToggleFullscreen, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
|
||||
TYPED_EVENT(ToggleCommandPalette, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
|
||||
TYPED_EVENT(ExecuteCommandline, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
|
||||
TYPED_EVENT(SetTabColor, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
|
||||
TYPED_EVENT(OpenTabColorPicker, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
|
||||
TYPED_EVENT(RenameTab, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
|
||||
|
||||
@@ -31,11 +31,11 @@ namespace TerminalApp
|
||||
ResizePane,
|
||||
MoveFocus,
|
||||
Find,
|
||||
ToggleRetroEffect,
|
||||
ToggleFullscreen,
|
||||
SetTabColor,
|
||||
OpenTabColorPicker,
|
||||
OpenSettings,
|
||||
ExecuteCommandline,
|
||||
RenameTab,
|
||||
ToggleCommandPalette
|
||||
};
|
||||
@@ -74,9 +74,9 @@ namespace TerminalApp
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> ResizePane;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> Find;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> MoveFocus;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> ToggleRetroEffect;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> ToggleFullscreen;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> ToggleCommandPalette;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> ExecuteCommandline;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> SetTabColor;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> OpenTabColorPicker;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> RenameTab;
|
||||
|
||||
@@ -875,6 +875,10 @@ namespace winrt::TerminalApp::implementation
|
||||
return _rootPane->PreCalculateAutoSplit(_activePane, availableSpace).value_or(SplitState::Vertical);
|
||||
}
|
||||
|
||||
bool Tab::PreCalculateCanSplit(SplitState splitType, winrt::Windows::Foundation::Size availableSpace) const
|
||||
{
|
||||
return _rootPane->PreCalculateCanSplit(_activePane, splitType, availableSpace).value_or(false);
|
||||
}
|
||||
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<>);
|
||||
|
||||
@@ -40,6 +40,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
float CalcSnappedDimension(const bool widthOrHeight, const float dimension) const;
|
||||
SplitState PreCalculateAutoSplit(winrt::Windows::Foundation::Size rootSize) const;
|
||||
bool PreCalculateCanSplit(SplitState splitType, winrt::Windows::Foundation::Size availableSpace) const;
|
||||
|
||||
void ResizeContent(const winrt::Windows::Foundation::Size& newSize);
|
||||
void ResizePane(const winrt::TerminalApp::Direction& direction);
|
||||
|
||||
@@ -31,8 +31,6 @@ the MIT License. See LICENSE in the project root for license information. -->
|
||||
FontFamily="Segoe MDL2 Assets"
|
||||
FontWeight="SemiLight"
|
||||
FontSize="12"
|
||||
BorderThickness="0"
|
||||
CornerRadius="{Binding Source={ThemeResource OverlayCornerRadius}, Converter={StaticResource TopCornerRadiusFilterConverter}}"
|
||||
AutomationProperties.AccessibilityView="Control">
|
||||
<!-- U+E710 is the fancy plus icon. -->
|
||||
<mux:SplitButton.Resources>
|
||||
@@ -40,28 +38,28 @@ the MIT License. See LICENSE in the project root for license information. -->
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<StaticResource x:Key="SplitButtonBackground" ResourceKey="TabViewButtonBackground" />
|
||||
<StaticResource x:Key="SplitButtonForeground" ResourceKey="TabViewButtonForeground" />
|
||||
<StaticResource x:Key="SplitButtonBackground" ResourceKey="TabViewItemHeaderBackground" />
|
||||
<StaticResource x:Key="SplitButtonForeground" ResourceKey="SystemControlBackgroundBaseMediumBrush" />
|
||||
<StaticResource x:Key="SplitButtonBackgroundPressed" ResourceKey="TabViewItemHeaderBackgroundPressed" />
|
||||
<StaticResource x:Key="SplitButtonForegroundPressed" ResourceKey="TabViewItemHeaderForegroundPressed" />
|
||||
<StaticResource x:Key="SplitButtonForegroundPressed" ResourceKey="SystemControlBackgroundBaseMediumHighBrush" />
|
||||
<StaticResource x:Key="SplitButtonBackgroundPointerOver" ResourceKey="TabViewItemHeaderBackgroundPointerOver" />
|
||||
<StaticResource x:Key="SplitButtonForegroundPointerOver" ResourceKey="TabViewItemHeaderForegroundPointerOver" />
|
||||
<StaticResource x:Key="SplitButtonForegroundPointerOver" ResourceKey="SystemControlBackgroundBaseMediumHighBrush" />
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
<StaticResource x:Key="SplitButtonBackground" ResourceKey="TabViewButtonBackground" />
|
||||
<StaticResource x:Key="SplitButtonForeground" ResourceKey="TabViewButtonForeground" />
|
||||
<StaticResource x:Key="SplitButtonBackground" ResourceKey="TabViewItemHeaderBackground" />
|
||||
<StaticResource x:Key="SplitButtonForeground" ResourceKey="SystemControlBackgroundBaseMediumBrush" />
|
||||
<StaticResource x:Key="SplitButtonBackgroundPressed" ResourceKey="TabViewItemHeaderBackgroundPressed" />
|
||||
<StaticResource x:Key="SplitButtonForegroundPressed" ResourceKey="TabViewItemHeaderForegroundPressed" />
|
||||
<StaticResource x:Key="SplitButtonForegroundPressed" ResourceKey="SystemControlBackgroundBaseMediumHighBrush" />
|
||||
<StaticResource x:Key="SplitButtonBackgroundPointerOver" ResourceKey="TabViewItemHeaderBackgroundPointerOver" />
|
||||
<StaticResource x:Key="SplitButtonForegroundPointerOver" ResourceKey="TabViewItemHeaderForegroundPointerOver" />
|
||||
<StaticResource x:Key="SplitButtonForegroundPointerOver" ResourceKey="SystemControlBackgroundBaseMediumHighBrush" />
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<StaticResource x:Key="SplitButtonBackground" ResourceKey="TabViewButtonBackground" />
|
||||
<StaticResource x:Key="SplitButtonForeground" ResourceKey="TabViewButtonForeground" />
|
||||
<StaticResource x:Key="SplitButtonBackground" ResourceKey="TabViewItemHeaderBackground" />
|
||||
<StaticResource x:Key="SplitButtonForeground" ResourceKey="SystemControlBackgroundBaseMediumBrush" />
|
||||
<StaticResource x:Key="SplitButtonBackgroundPressed" ResourceKey="TabViewItemHeaderBackgroundPressed" />
|
||||
<StaticResource x:Key="SplitButtonForegroundPressed" ResourceKey="TabViewItemHeaderForegroundPressed" />
|
||||
<StaticResource x:Key="SplitButtonForegroundPressed" ResourceKey="SystemControlBackgroundBaseMediumHighBrush" />
|
||||
<StaticResource x:Key="SplitButtonBackgroundPointerOver" ResourceKey="TabViewItemHeaderBackgroundPointerOver" />
|
||||
<StaticResource x:Key="SplitButtonForegroundPointerOver" ResourceKey="TabViewItemHeaderForegroundPointerOver" />
|
||||
<StaticResource x:Key="SplitButtonForegroundPointerOver" ResourceKey="SystemControlBackgroundBaseMediumHighBrush" />
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
</ResourceDictionary>
|
||||
|
||||
@@ -79,13 +79,13 @@
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.4.2-prerelease.200604001\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.4.2-prerelease.200604001\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.4.2-prerelease.200604001\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.4.2-prerelease.200604001\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
|
||||
</Target>
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
using namespace winrt;
|
||||
using namespace winrt::Windows::Foundation::Collections;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Xaml::Controls;
|
||||
using namespace winrt::Windows::UI::Core;
|
||||
using namespace winrt::Windows::System;
|
||||
using namespace winrt::Windows::ApplicationModel::DataTransfer;
|
||||
@@ -231,7 +230,7 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
else
|
||||
{
|
||||
_ProcessStartupActions();
|
||||
_ProcessStartupActions(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -240,10 +239,11 @@ namespace winrt::TerminalApp::implementation
|
||||
// - Process all the startup actions in our list of startup actions. We'll
|
||||
// do this all at once here.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// - initial: if true, we're parsing these args during startup, and we
|
||||
// should fire an Initialized event.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
winrt::fire_and_forget TerminalPage::_ProcessStartupActions()
|
||||
winrt::fire_and_forget TerminalPage::_ProcessStartupActions(const bool initial)
|
||||
{
|
||||
// If there are no actions left, do nothing.
|
||||
if (_startupActions.empty())
|
||||
@@ -253,15 +253,24 @@ namespace winrt::TerminalApp::implementation
|
||||
auto weakThis{ get_weak() };
|
||||
|
||||
// Handle it on a subsequent pass of the UI thread.
|
||||
co_await winrt::resume_foreground(Dispatcher(), CoreDispatcherPriority::Normal);
|
||||
if (auto page{ weakThis.get() })
|
||||
for (const auto& action : _startupActions)
|
||||
{
|
||||
for (const auto& action : _startupActions)
|
||||
co_await winrt::resume_foreground(Dispatcher(), CoreDispatcherPriority::Normal);
|
||||
if (auto page{ weakThis.get() })
|
||||
{
|
||||
_actionDispatch->DoAction(action);
|
||||
}
|
||||
|
||||
_CompleteInitialization();
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (auto page{ weakThis.get() })
|
||||
{
|
||||
if (initial)
|
||||
{
|
||||
_CompleteInitialization();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,10 +294,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// Notes link, and privacy policy link.
|
||||
void TerminalPage::_ShowAboutDialog()
|
||||
{
|
||||
if (auto presenter{ _dialogPresenter.get() })
|
||||
{
|
||||
presenter.ShowDialog(FindName(L"AboutDialog").try_as<WUX::Controls::ContentDialog>());
|
||||
}
|
||||
_showDialogHandlers(*this, FindName(L"AboutDialog").try_as<WUX::Controls::ContentDialog>());
|
||||
}
|
||||
|
||||
winrt::hstring TerminalPage::ApplicationDisplayName()
|
||||
@@ -327,42 +333,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// when this is called, nothing happens. See _ShowDialog for details
|
||||
void TerminalPage::_ShowCloseWarningDialog()
|
||||
{
|
||||
if (auto presenter{ _dialogPresenter.get() })
|
||||
{
|
||||
presenter.ShowDialog(FindName(L"CloseAllDialog").try_as<WUX::Controls::ContentDialog>());
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Displays a dialog to warn the user about the fact that the text that
|
||||
// they are trying to paste contains the "new line" character which can
|
||||
// have the effect of starting commands without the user's knowledge if
|
||||
// it is pasted on a shell where the "new line" character marks the end
|
||||
// of a command.
|
||||
// - Only one dialog can be visible at a time. If another dialog is visible
|
||||
// when this is called, nothing happens. See _ShowDialog for details
|
||||
winrt::Windows::Foundation::IAsyncOperation<ContentDialogResult> TerminalPage::_ShowMultiLinePasteWarningDialog()
|
||||
{
|
||||
if (auto presenter{ _dialogPresenter.get() })
|
||||
{
|
||||
co_return co_await presenter.ShowDialog(FindName(L"MultiLinePasteDialog").try_as<WUX::Controls::ContentDialog>());
|
||||
}
|
||||
co_return ContentDialogResult::None;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Displays a dialog to warn the user about the fact that the text that
|
||||
// they are trying to paste is very long, in case they did not mean to
|
||||
// paste it but pressed the paste shortcut by accident.
|
||||
// - Only one dialog can be visible at a time. If another dialog is visible
|
||||
// when this is called, nothing happens. See _ShowDialog for details
|
||||
winrt::Windows::Foundation::IAsyncOperation<ContentDialogResult> TerminalPage::_ShowLargePasteWarningDialog()
|
||||
{
|
||||
if (auto presenter{ _dialogPresenter.get() })
|
||||
{
|
||||
co_return co_await presenter.ShowDialog(FindName(L"LargePasteDialog").try_as<WUX::Controls::ContentDialog>());
|
||||
}
|
||||
co_return ContentDialogResult::None;
|
||||
_showDialogHandlers(*this, FindName(L"CloseAllDialog").try_as<WUX::Controls::ContentDialog>());
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -554,13 +525,6 @@ namespace winrt::TerminalApp::implementation
|
||||
const bool usedManualProfile = (newTerminalArgs != nullptr) &&
|
||||
(newTerminalArgs.ProfileIndex() != nullptr ||
|
||||
newTerminalArgs.Profile().empty());
|
||||
|
||||
// Lookup the name of the color scheme used by this profile.
|
||||
const auto* scheme = _settings->GetColorSchemeForProfile(profileGuid);
|
||||
// If they explicitly specified `null` as the scheme (indicating _no_ scheme), log
|
||||
// that as the empty string.
|
||||
const auto schemeName = scheme ? scheme->GetName() : L"\0";
|
||||
|
||||
TraceLoggingWrite(
|
||||
g_hTerminalAppProvider, // handle to TerminalApp tracelogging provider
|
||||
"TabInformation",
|
||||
@@ -572,7 +536,6 @@ namespace winrt::TerminalApp::implementation
|
||||
TraceLoggingBool(settings.UseAcrylic(), "UseAcrylic", "The acrylic preference from the settings"),
|
||||
TraceLoggingFloat64(settings.TintOpacity(), "TintOpacity", "Opacity preference from the settings"),
|
||||
TraceLoggingWideString(settings.FontFace().c_str(), "FontFace", "Font face chosen in the settings"),
|
||||
TraceLoggingWideString(schemeName.data(), "SchemeName", "Color scheme set in the settings"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance));
|
||||
}
|
||||
@@ -642,16 +605,6 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
auto tabViewItem = newTabImpl->GetTabViewItem();
|
||||
_tabView.TabItems().Append(tabViewItem);
|
||||
// GH#6570
|
||||
// The TabView does not apply compact sizing to items added after Compact is enabled.
|
||||
// By forcibly reapplying compact sizing every time we add a new tab, we'll make sure
|
||||
// that it works.
|
||||
// Workaround from https://github.com/microsoft/microsoft-ui-xaml/issues/2711
|
||||
if (_tabView.TabWidthMode() == MUX::Controls::TabViewWidthMode::Compact)
|
||||
{
|
||||
_tabView.UpdateLayout();
|
||||
_tabView.TabWidthMode(MUX::Controls::TabViewWidthMode::Compact);
|
||||
}
|
||||
|
||||
// Set this tab's icon to the icon from the user's profile
|
||||
const auto* const profile = _settings->FindProfile(profileGuid);
|
||||
@@ -849,9 +802,9 @@ namespace winrt::TerminalApp::implementation
|
||||
_actionDispatch->AdjustFontSize({ this, &TerminalPage::_HandleAdjustFontSize });
|
||||
_actionDispatch->Find({ this, &TerminalPage::_HandleFind });
|
||||
_actionDispatch->ResetFontSize({ this, &TerminalPage::_HandleResetFontSize });
|
||||
_actionDispatch->ToggleRetroEffect({ this, &TerminalPage::_HandleToggleRetroEffect });
|
||||
_actionDispatch->ToggleFullscreen({ this, &TerminalPage::_HandleToggleFullscreen });
|
||||
_actionDispatch->ToggleCommandPalette({ this, &TerminalPage::_HandleToggleCommandPalette });
|
||||
_actionDispatch->ExecuteCommandline({ this, &TerminalPage::_HandleExecuteCommandline });
|
||||
_actionDispatch->SetTabColor({ this, &TerminalPage::_HandleSetTabColor });
|
||||
_actionDispatch->OpenTabColorPicker({ this, &TerminalPage::_HandleOpenTabColorPicker });
|
||||
_actionDispatch->RenameTab({ this, &TerminalPage::_HandleRenameTab });
|
||||
@@ -1362,19 +1315,20 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
const auto controlConnection = _CreateConnectionFromSettings(realGuid, controlSettings);
|
||||
|
||||
const auto canSplit = focusedTab->CanSplitPane(splitType);
|
||||
|
||||
if (!canSplit && _startupState == StartupState::Initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
float contentWidth = gsl::narrow_cast<float>(_tabContent.ActualWidth());
|
||||
float contentHeight = gsl::narrow_cast<float>(_tabContent.ActualHeight());
|
||||
winrt::Windows::Foundation::Size availableSpace{ contentWidth, contentHeight };
|
||||
|
||||
auto realSplitType = splitType;
|
||||
if (realSplitType == SplitState::Automatic && _startupState < StartupState::Initialized)
|
||||
if (realSplitType == SplitState::Automatic)
|
||||
{
|
||||
float contentWidth = gsl::narrow_cast<float>(_tabContent.ActualWidth());
|
||||
float contentHeight = gsl::narrow_cast<float>(_tabContent.ActualHeight());
|
||||
realSplitType = focusedTab->PreCalculateAutoSplit({ contentWidth, contentHeight });
|
||||
realSplitType = focusedTab->PreCalculateAutoSplit(availableSpace);
|
||||
}
|
||||
|
||||
const auto canSplit = focusedTab->PreCalculateCanSplit(realSplitType, availableSpace);
|
||||
if (!canSplit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TermControl newControl{ controlSettings, controlConnection };
|
||||
@@ -1584,19 +1538,26 @@ namespace winrt::TerminalApp::implementation
|
||||
CATCH_LOG();
|
||||
}
|
||||
|
||||
// Function Description:
|
||||
// - This function is called when the `TermControl` requests that we send
|
||||
// it the clipboard's content.
|
||||
// - Retrieves the data from the Windows Clipboard and converts it to text.
|
||||
// - Shows warnings if the clipboard is too big or contains multiple lines
|
||||
// of text.
|
||||
// - Sends the text back to the TermControl through the event's
|
||||
// `HandleClipboardData` member function.
|
||||
// - Does some of this in a background thread, as to not hang/crash the UI thread.
|
||||
// Method Description:
|
||||
// - Fires an async event to get data from the clipboard, and paste it to
|
||||
// the terminal. Triggered when the Terminal Control requests clipboard
|
||||
// data with it's PasteFromClipboard event.
|
||||
// Arguments:
|
||||
// - eventArgs: the PasteFromClipboard event sent from the TermControl
|
||||
fire_and_forget TerminalPage::_PasteFromClipboardHandler(const IInspectable /*sender*/,
|
||||
const PasteFromClipboardEventArgs eventArgs)
|
||||
winrt::fire_and_forget TerminalPage::_PasteFromClipboardHandler(const IInspectable /*sender*/,
|
||||
const PasteFromClipboardEventArgs eventArgs)
|
||||
{
|
||||
co_await winrt::resume_foreground(Dispatcher(), CoreDispatcherPriority::High);
|
||||
|
||||
TerminalPage::PasteFromClipboard(eventArgs);
|
||||
}
|
||||
|
||||
// Function Description:
|
||||
// - Copies and processes the text data from the Windows Clipboard.
|
||||
// Does some of this in a background thread, as to not hang/crash the UI thread.
|
||||
// Arguments:
|
||||
// - eventArgs: the PasteFromClipboard event sent from the TermControl
|
||||
fire_and_forget TerminalPage::PasteFromClipboard(PasteFromClipboardEventArgs eventArgs)
|
||||
{
|
||||
const DataPackageView data = Clipboard::GetContent();
|
||||
|
||||
@@ -1622,35 +1583,6 @@ namespace winrt::TerminalApp::implementation
|
||||
text = item.Path();
|
||||
}
|
||||
}
|
||||
|
||||
const bool hasNewLine = std::find(text.cbegin(), text.cend(), L'\n') != text.cend();
|
||||
const bool warnMultiLine = hasNewLine && _settings->GlobalSettings().WarnAboutMultiLinePaste();
|
||||
|
||||
constexpr const std::size_t minimumSizeForWarning = 1024 * 5; // 5 KiB
|
||||
const bool warnLargeText = text.size() > minimumSizeForWarning &&
|
||||
_settings->GlobalSettings().WarnAboutLargePaste();
|
||||
|
||||
if (warnMultiLine || warnLargeText)
|
||||
{
|
||||
co_await winrt::resume_foreground(Dispatcher());
|
||||
|
||||
ContentDialogResult warningResult;
|
||||
if (warnMultiLine)
|
||||
{
|
||||
warningResult = co_await _ShowMultiLinePasteWarningDialog();
|
||||
}
|
||||
else if (warnLargeText)
|
||||
{
|
||||
warningResult = co_await _ShowLargePasteWarningDialog();
|
||||
}
|
||||
|
||||
if (warningResult != ContentDialogResult::Primary)
|
||||
{
|
||||
// user rejected the paste
|
||||
co_return;
|
||||
}
|
||||
}
|
||||
|
||||
eventArgs.HandleClipboardData(text);
|
||||
}
|
||||
CATCH_LOG();
|
||||
@@ -1927,16 +1859,6 @@ namespace winrt::TerminalApp::implementation
|
||||
_startupActions = actions;
|
||||
}
|
||||
|
||||
winrt::TerminalApp::IDialogPresenter TerminalPage::DialogPresenter() const
|
||||
{
|
||||
return _dialogPresenter.get();
|
||||
}
|
||||
|
||||
void TerminalPage::DialogPresenter(winrt::TerminalApp::IDialogPresenter dialogPresenter)
|
||||
{
|
||||
_dialogPresenter = dialogPresenter;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - This is the method that App will call when the titlebar
|
||||
// has been clicked. It dismisses any open flyouts.
|
||||
@@ -2176,5 +2098,6 @@ namespace winrt::TerminalApp::implementation
|
||||
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TerminalPage, TitleChanged, _titleChangeHandlers, winrt::Windows::Foundation::IInspectable, winrt::hstring);
|
||||
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TerminalPage, LastTabClosed, _lastTabClosedHandlers, winrt::Windows::Foundation::IInspectable, winrt::TerminalApp::LastTabClosedEventArgs);
|
||||
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TerminalPage, SetTitleBarContent, _setTitleBarContentHandlers, winrt::Windows::Foundation::IInspectable, UIElement);
|
||||
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TerminalPage, ShowDialog, _showDialogHandlers, winrt::Windows::Foundation::IInspectable, WUX::Controls::ContentDialog);
|
||||
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TerminalPage, ToggleFullscreen, _toggleFullscreenHandlers, winrt::Windows::Foundation::IInspectable, winrt::TerminalApp::ToggleFullscreenEventArgs);
|
||||
}
|
||||
|
||||
@@ -53,13 +53,11 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void SetStartupActions(std::deque<winrt::TerminalApp::ActionAndArgs>& actions);
|
||||
|
||||
winrt::TerminalApp::IDialogPresenter DialogPresenter() const;
|
||||
void DialogPresenter(winrt::TerminalApp::IDialogPresenter dialogPresenter);
|
||||
|
||||
// -------------------------------- WinRT Events ---------------------------------
|
||||
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(TitleChanged, _titleChangeHandlers, winrt::Windows::Foundation::IInspectable, winrt::hstring);
|
||||
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(LastTabClosed, _lastTabClosedHandlers, winrt::Windows::Foundation::IInspectable, winrt::TerminalApp::LastTabClosedEventArgs);
|
||||
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(SetTitleBarContent, _setTitleBarContentHandlers, winrt::Windows::Foundation::IInspectable, winrt::Windows::UI::Xaml::UIElement);
|
||||
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(ShowDialog, _showDialogHandlers, winrt::Windows::Foundation::IInspectable, winrt::Windows::UI::Xaml::Controls::ContentDialog);
|
||||
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(ToggleFullscreen, _toggleFullscreenHandlers, winrt::Windows::Foundation::IInspectable, winrt::TerminalApp::ToggleFullscreenEventArgs);
|
||||
TYPED_EVENT(Initialized, winrt::Windows::Foundation::IInspectable, winrt::Windows::UI::Xaml::RoutedEventArgs);
|
||||
|
||||
@@ -89,21 +87,16 @@ namespace winrt::TerminalApp::implementation
|
||||
std::optional<int> _rearrangeFrom;
|
||||
std::optional<int> _rearrangeTo;
|
||||
|
||||
// use a weak reference to prevent circular dependency with AppLogic
|
||||
winrt::weak_ref<winrt::TerminalApp::IDialogPresenter> _dialogPresenter;
|
||||
|
||||
winrt::com_ptr<ShortcutActionDispatch> _actionDispatch{ winrt::make_self<ShortcutActionDispatch>() };
|
||||
|
||||
winrt::Windows::UI::Xaml::Controls::Grid::LayoutUpdated_revoker _layoutUpdatedRevoker;
|
||||
StartupState _startupState{ StartupState::NotInitialized };
|
||||
|
||||
std::deque<winrt::TerminalApp::ActionAndArgs> _startupActions;
|
||||
winrt::fire_and_forget _ProcessStartupActions();
|
||||
winrt::fire_and_forget _ProcessStartupActions(const bool initial);
|
||||
|
||||
void _ShowAboutDialog();
|
||||
void _ShowCloseWarningDialog();
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> _ShowMultiLinePasteWarningDialog();
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> _ShowLargePasteWarningDialog();
|
||||
|
||||
void _CreateNewTabFlyout();
|
||||
void _OpenNewTabDropdown();
|
||||
@@ -157,6 +150,7 @@ namespace winrt::TerminalApp::implementation
|
||||
const Microsoft::Terminal::TerminalControl::PasteFromClipboardEventArgs eventArgs);
|
||||
bool _CopyText(const bool trimTrailingWhitespace);
|
||||
void _PasteText();
|
||||
static fire_and_forget PasteFromClipboard(winrt::Microsoft::Terminal::TerminalControl::PasteFromClipboardEventArgs eventArgs);
|
||||
|
||||
fire_and_forget _LaunchSettings(const winrt::TerminalApp::SettingsTarget target);
|
||||
|
||||
@@ -205,12 +199,12 @@ namespace winrt::TerminalApp::implementation
|
||||
void _HandleAdjustFontSize(const IInspectable& sender, const TerminalApp::ActionEventArgs& args);
|
||||
void _HandleFind(const IInspectable& sender, const TerminalApp::ActionEventArgs& args);
|
||||
void _HandleResetFontSize(const IInspectable& sender, const TerminalApp::ActionEventArgs& args);
|
||||
void _HandleToggleRetroEffect(const IInspectable& sender, const TerminalApp::ActionEventArgs& args);
|
||||
void _HandleToggleFullscreen(const IInspectable& sender, const TerminalApp::ActionEventArgs& args);
|
||||
void _HandleSetTabColor(const IInspectable& sender, const TerminalApp::ActionEventArgs& args);
|
||||
void _HandleOpenTabColorPicker(const IInspectable& sender, const TerminalApp::ActionEventArgs& args);
|
||||
void _HandleRenameTab(const IInspectable& sender, const TerminalApp::ActionEventArgs& args);
|
||||
void _HandleToggleCommandPalette(const IInspectable& sender, const TerminalApp::ActionEventArgs& args);
|
||||
void _HandleExecuteCommandline(const IInspectable& sender, const TerminalApp::ActionEventArgs& args);
|
||||
// Make sure to hook new actions up in _RegisterActionCallbacks!
|
||||
#pragma endregion
|
||||
|
||||
|
||||
@@ -6,11 +6,6 @@ namespace TerminalApp
|
||||
delegate void LastTabClosedEventArgs();
|
||||
delegate void ToggleFullscreenEventArgs();
|
||||
|
||||
interface IDialogPresenter
|
||||
{
|
||||
Windows.Foundation.IAsyncOperation<Windows.UI.Xaml.Controls.ContentDialogResult> ShowDialog(Windows.UI.Xaml.Controls.ContentDialog dialog);
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass TerminalPage : Windows.UI.Xaml.Controls.Page
|
||||
{
|
||||
TerminalPage();
|
||||
@@ -19,14 +14,10 @@ namespace TerminalApp
|
||||
String ApplicationDisplayName { get; };
|
||||
String ApplicationVersion { get; };
|
||||
|
||||
// We cannot use the default XAML APIs because we want to make sure
|
||||
// that there's only one application-global dialog visible at a time,
|
||||
// and because of GH#5224.
|
||||
IDialogPresenter DialogPresenter;
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<Object, String> TitleChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, LastTabClosedEventArgs> LastTabClosed;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Windows.UI.Xaml.UIElement> SetTitleBarContent;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Windows.UI.Xaml.Controls.ContentDialog> ShowDialog;
|
||||
event Windows.Foundation.TypedEventHandler<Object, ToggleFullscreenEventArgs> ToggleFullscreen;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Windows.UI.Xaml.RoutedEventArgs> Initialized;
|
||||
}
|
||||
|
||||
@@ -54,20 +54,6 @@ the MIT License. See LICENSE in the project root for license information. -->
|
||||
PrimaryButtonClick="_CloseWarningPrimaryButtonOnClick">
|
||||
</ContentDialog>
|
||||
|
||||
<ContentDialog
|
||||
x:Load="False"
|
||||
x:Name="MultiLinePasteDialog"
|
||||
x:Uid="MultiLinePasteDialog"
|
||||
DefaultButton="Primary">
|
||||
</ContentDialog>
|
||||
|
||||
<ContentDialog
|
||||
x:Load="False"
|
||||
x:Name="LargePasteDialog"
|
||||
x:Uid="LargePasteDialog"
|
||||
DefaultButton="Primary">
|
||||
</ContentDialog>
|
||||
|
||||
<local:CommandPalette
|
||||
x:Name="CommandPalette"
|
||||
Grid.Row="1"
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
{
|
||||
"guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
|
||||
"name": "Windows PowerShell",
|
||||
"commandline": "%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
|
||||
"commandline": "powershell.exe",
|
||||
"icon": "ms-appx:///ProfileIcons/{61c54bbd-c2c6-5271-96e7-009a87ff44bf}.png",
|
||||
"colorScheme": "Campbell",
|
||||
"antialiasingMode": "grayscale",
|
||||
@@ -49,7 +49,7 @@
|
||||
{
|
||||
"guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
|
||||
"name": "Command Prompt",
|
||||
"commandline": "%SystemRoot%\\System32\\cmd.exe",
|
||||
"commandline": "cmd.exe",
|
||||
"icon": "ms-appx:///ProfileIcons/{0caa0dad-35be-5f56-a8ff-afceeeaa6101}.png",
|
||||
"colorScheme": "Campbell",
|
||||
"antialiasingMode": "grayscale",
|
||||
@@ -271,7 +271,7 @@
|
||||
"brightWhite": "#EEEEEC"
|
||||
}
|
||||
],
|
||||
"bindings":
|
||||
"keybindings":
|
||||
[
|
||||
// Application-level Keys
|
||||
{ "command": "closeWindow", "keys": "alt+f4" },
|
||||
@@ -281,8 +281,6 @@
|
||||
{ "command": "openSettings", "keys": "ctrl+," },
|
||||
{ "command": { "action": "openSettings", "target": "defaultsFile" }, "keys": "ctrl+alt+," },
|
||||
{ "command": "find", "keys": "ctrl+shift+f" },
|
||||
{ "command": "toggleRetroEffect" },
|
||||
{ "command": "openTabColorPicker" },
|
||||
|
||||
// Tab Management
|
||||
// "command": "closeTab" is unbound by default.
|
||||
|
||||
@@ -94,9 +94,6 @@
|
||||
<ClInclude Include="../Command.h">
|
||||
<DependentUpon>../Command.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="../CommandKeyChordVisibilityConverter.h">
|
||||
<DependentUpon>../CommandKeyChordVisibilityConverter.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="../Tab.h">
|
||||
<DependentUpon>../Tab.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
@@ -164,9 +161,6 @@
|
||||
<ClCompile Include="../Command.cpp">
|
||||
<DependentUpon>../Command.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="../CommandKeyChordVisibilityConverter.cpp">
|
||||
<DependentUpon>../CommandKeyChordVisibilityConverter.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="../Tab.cpp">
|
||||
<DependentUpon>../Tab.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
@@ -255,7 +249,6 @@
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="../Command.idl" />
|
||||
<Midl Include="../CommandKeyChordVisibilityConverter.idl" />
|
||||
<Midl Include="../Tab.idl" />
|
||||
</ItemGroup>
|
||||
<!-- ========================= Misc Files ======================== -->
|
||||
@@ -330,13 +323,13 @@
|
||||
<!-- ========================= Globals ======================== -->
|
||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
|
||||
|
||||
<Import Project="..\..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.UI.Xaml.2.4.2-prerelease.200604001\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\..\packages\Microsoft.UI.Xaml.2.4.2-prerelease.200604001\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.4.2-prerelease.200604001\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.4.2-prerelease.200604001\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
|
||||
</Target>
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
#include <winrt/Windows.Foundation.Metadata.h>
|
||||
#include <winrt/Windows.Graphics.Display.h>
|
||||
#include <winrt/windows.ui.core.h>
|
||||
#include <winrt/Windows.ui.input.h>
|
||||
#include <winrt/Windows.UI.Text.h>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.0.0" targetFramework="native" />
|
||||
<package id="Microsoft.UI.Xaml" version="2.5.0-prerelease.200609001" targetFramework="native" />
|
||||
<package id="Microsoft.UI.Xaml" version="2.4.2-prerelease.200604001" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.200316.3" targetFramework="native" />
|
||||
</packages>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "AzureConnection.h"
|
||||
#include "AzureClientID.h"
|
||||
#include <sstream>
|
||||
#include <cstdlib>
|
||||
#include <stdlib.h>
|
||||
#include <LibraryResources.h>
|
||||
#include <unicode.hpp>
|
||||
|
||||
|
||||
@@ -383,47 +383,6 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
}
|
||||
CATCH_LOG()
|
||||
|
||||
static auto channelpair = til::spsc::channel<wchar_t>(16 * 1024);
|
||||
static ConptyConnection* obj = nullptr;
|
||||
static void terminalOutputHandlerMethod()
|
||||
{
|
||||
std::vector<wchar_t> buf(16 * 1024, L'\0');
|
||||
|
||||
while (true)
|
||||
{
|
||||
// OK. So this is going to go all the way down to a winrt::hstring.
|
||||
// "But!", you say, "isn't a `std::wstring_view` like we're creating for the passing
|
||||
// (to avoid a copy) not guaranteed to be null terminated?"
|
||||
// Well, yes, you're right. However, the `winrt::hstring(std::wstring_view)` constuctor
|
||||
// doesn't seem to care about that. It has the full intent of just taking the data pointer
|
||||
// and embedding it inside itself as the hstring reference (instead of copying).
|
||||
// That's a good thing. Except that hstrings have to be null terminated.
|
||||
// So it contains a beautiful check for str[size] != 0 to ensure that the view you gave it
|
||||
// was null terminated and it just flat out `std::terminate`s you if it's not. (You know
|
||||
// instead of doing something like copying it or throwing or documenting any of these facts
|
||||
// in either the header, the constructor, or on MSDN.)
|
||||
|
||||
auto [count, ok] = channelpair.second.pop_n(til::spsc::block_initially, buf.data(), buf.size() - 1);
|
||||
if (!ok)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Make sure the end of it is null or risk the wrath of `winrt::hstring` when we hit the
|
||||
// WinRT event callback on the way out of this module (see above).
|
||||
buf[count] = '\0';
|
||||
|
||||
obj->_DoOutputThreadWork(std::wstring_view{ buf.data(), count });
|
||||
}
|
||||
}
|
||||
|
||||
static std::thread th(terminalOutputHandlerMethod);
|
||||
|
||||
void ConptyConnection::_DoOutputThreadWork(std::wstring_view str)
|
||||
{
|
||||
_TerminalOutputHandlers(str);
|
||||
}
|
||||
|
||||
DWORD ConptyConnection::_OutputThread()
|
||||
{
|
||||
// Keep us alive until the output thread terminates; the destructor
|
||||
@@ -486,13 +445,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
}
|
||||
|
||||
// Pass the output to our registered event handlers
|
||||
if (!obj)
|
||||
{
|
||||
obj = this;
|
||||
}
|
||||
channelpair.first.push_n(_u16Str.data(), _u16Str.size());
|
||||
|
||||
//_TerminalOutputHandlers(_u16Str);
|
||||
_TerminalOutputHandlers(_u16Str);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -66,9 +66,6 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
std::array<char, 4096> _buffer;
|
||||
|
||||
DWORD _OutputThread();
|
||||
|
||||
public:
|
||||
void _DoOutputThreadWork(std::wstring_view str);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
<Style x:Key="SearchBoxBackground" TargetType="StackPanel">
|
||||
<Setter Property="Background" Value="#333333" />
|
||||
</Style>
|
||||
<Style x:Key="PathStyle" TargetType="PathIcon" />
|
||||
<!-- TextBox colors !-->
|
||||
<SolidColorBrush x:Key="TextControlBackground" Color="#333333"/>
|
||||
<SolidColorBrush x:Key="TextBoxPlaceholderTextThemeBrush" Color="#B5B5B5"/>
|
||||
@@ -93,6 +94,7 @@
|
||||
<Style x:Key="SearchBoxBackground" TargetType="StackPanel">
|
||||
<Setter Property="Background" Value="#CCCCCC" />
|
||||
</Style>
|
||||
<Style x:Key="PathStyle" TargetType="PathIcon" />
|
||||
<!-- TextBox colors !-->
|
||||
<SolidColorBrush x:Key="TextControlBackground" Color="#CCCCCC"/>
|
||||
<SolidColorBrush x:Key="TextBoxPlaceholderTextThemeBrush" Color="#636363"/>
|
||||
@@ -142,10 +144,14 @@
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<Style x:Key="FontIconStyle" TargetType="FontIcon">
|
||||
<Setter Property="FontSize" Value="12" />
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemColorWindowTextColor}" />
|
||||
</Style>
|
||||
<Style x:Key="SearchBoxBackground" TargetType="StackPanel">
|
||||
<Setter Property="Background" Value="{ThemeResource SystemColorWindowColor}" />
|
||||
</Style>
|
||||
<Style x:Key="PathStyle" TargetType="PathIcon">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemColorWindowTextColor}" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
</ResourceDictionary>
|
||||
@@ -182,7 +188,8 @@
|
||||
<ToggleButton x:Name="CaseSensitivityButton"
|
||||
x:Uid="SearchBox_CaseSensitivity"
|
||||
Style="{StaticResource ToggleButtonStyle}">
|
||||
<PathIcon Data="M8.87305 10H7.60156L6.5625 7.25195H2.40625L1.42871 10H0.150391L3.91016 0.197266H5.09961L8.87305 10ZM6.18652 6.21973L4.64844 2.04297C4.59831 1.90625 4.54818 1.6875 4.49805 1.38672H4.4707C4.42513 1.66471 4.37272 1.88346 4.31348 2.04297L2.78906 6.21973H6.18652ZM15.1826 10H14.0615V8.90625H14.0342C13.5465 9.74479 12.8288 10.1641 11.8809 10.1641C11.1836 10.1641 10.6367 9.97949 10.2402 9.61035C9.84831 9.24121 9.65234 8.7513 9.65234 8.14062C9.65234 6.83268 10.4225 6.07161 11.9629 5.85742L14.0615 5.56348C14.0615 4.37402 13.5807 3.7793 12.6191 3.7793C11.776 3.7793 11.015 4.06641 10.3359 4.64062V3.49219C11.0241 3.05469 11.8171 2.83594 12.7148 2.83594C14.36 2.83594 15.1826 3.70638 15.1826 5.44727V10ZM14.0615 6.45898L12.373 6.69141C11.8535 6.76432 11.4616 6.89421 11.1973 7.08105C10.9329 7.26335 10.8008 7.58919 10.8008 8.05859C10.8008 8.40039 10.9215 8.68066 11.1631 8.89941C11.4092 9.11361 11.735 9.2207 12.1406 9.2207C12.6966 9.2207 13.1546 9.02702 13.5146 8.63965C13.8792 8.24772 14.0615 7.75326 14.0615 7.15625V6.45898Z"/>
|
||||
<PathIcon Data="M8.87305 10H7.60156L6.5625 7.25195H2.40625L1.42871 10H0.150391L3.91016 0.197266H5.09961L8.87305 10ZM6.18652 6.21973L4.64844 2.04297C4.59831 1.90625 4.54818 1.6875 4.49805 1.38672H4.4707C4.42513 1.66471 4.37272 1.88346 4.31348 2.04297L2.78906 6.21973H6.18652ZM15.1826 10H14.0615V8.90625H14.0342C13.5465 9.74479 12.8288 10.1641 11.8809 10.1641C11.1836 10.1641 10.6367 9.97949 10.2402 9.61035C9.84831 9.24121 9.65234 8.7513 9.65234 8.14062C9.65234 6.83268 10.4225 6.07161 11.9629 5.85742L14.0615 5.56348C14.0615 4.37402 13.5807 3.7793 12.6191 3.7793C11.776 3.7793 11.015 4.06641 10.3359 4.64062V3.49219C11.0241 3.05469 11.8171 2.83594 12.7148 2.83594C14.36 2.83594 15.1826 3.70638 15.1826 5.44727V10ZM14.0615 6.45898L12.373 6.69141C11.8535 6.76432 11.4616 6.89421 11.1973 7.08105C10.9329 7.26335 10.8008 7.58919 10.8008 8.05859C10.8008 8.40039 10.9215 8.68066 11.1631 8.89941C11.4092 9.11361 11.735 9.2207 12.1406 9.2207C12.6966 9.2207 13.1546 9.02702 13.5146 8.63965C13.8792 8.24772 14.0615 7.75326 14.0615 7.15625V6.45898Z"
|
||||
Style="{ThemeResource PathStyle}" />
|
||||
</ToggleButton>
|
||||
|
||||
<Button x:Name="CloseButton"
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
using namespace ::Microsoft::Console::Types;
|
||||
using namespace ::Microsoft::Terminal::Core;
|
||||
using namespace winrt::Windows::Graphics::Display;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Xaml::Input;
|
||||
using namespace winrt::Windows::UI::Xaml::Automation::Peers;
|
||||
@@ -96,9 +97,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
auto pfnTerminalCursorPositionChanged = std::bind(&TermControl::_TerminalCursorPositionChanged, this);
|
||||
_terminal->SetCursorPositionChangedCallback(pfnTerminalCursorPositionChanged);
|
||||
|
||||
auto pfnCopyToClipboard = std::bind(&TermControl::_CopyToClipboard, this, std::placeholders::_1);
|
||||
_terminal->SetCopyToClipboardCallback(pfnCopyToClipboard);
|
||||
|
||||
// This event is explicitly revoked in the destructor: does not need weak_ref
|
||||
auto onReceiveOutputFn = [this](const hstring str) {
|
||||
_terminal->Write(str);
|
||||
@@ -297,11 +295,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
}
|
||||
}
|
||||
}
|
||||
void TermControl::ToggleRetroEffect()
|
||||
{
|
||||
auto lock = _terminal->LockForWriting();
|
||||
_renderEngine->SetRetroTerminalEffects(!_renderEngine->GetRetroTerminalEffects());
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Style our UI elements based on the values in our _settings, and set up
|
||||
@@ -629,7 +622,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
// Then, using the font, get the number of characters that can fit.
|
||||
// Resize our terminal connection to match that size, and initialize the terminal with that size.
|
||||
const auto viewInPixels = Viewport::FromDimensions({ 0, 0 }, windowSize);
|
||||
THROW_IF_FAILED(dxEngine->SetWindowSize({ viewInPixels.Width(), viewInPixels.Height() }));
|
||||
LOG_IF_FAILED(dxEngine->SetWindowSize({ viewInPixels.Width(), viewInPixels.Height() }));
|
||||
|
||||
// Update DxEngine's SelectionBackground
|
||||
dxEngine->SetSelectionBackground(_settings.SelectionBackground());
|
||||
@@ -2033,14 +2026,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
_titleChangedHandlers(winrt::hstring{ wstr });
|
||||
}
|
||||
|
||||
void TermControl::_CopyToClipboard(const std::wstring_view& wstr)
|
||||
{
|
||||
auto copyArgs = winrt::make_self<CopyToClipboardEventArgs>(winrt::hstring(wstr),
|
||||
winrt::hstring(L""),
|
||||
winrt::hstring(L""));
|
||||
_clipboardCopyHandlers(*this, *copyArgs);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Update the position and size of the scrollbar to match the given
|
||||
// viewport top, viewport height, and buffer size.
|
||||
@@ -2258,28 +2243,68 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
// as font size, scrollbar and other control scaling, etc. Make sure the
|
||||
// caller knows what monitor the control is about to appear on.
|
||||
// Return Value:
|
||||
// - a point containing the requested dimensions in pixels.
|
||||
winrt::Windows::Foundation::Point TermControl::GetProposedDimensions(IControlSettings const& settings, const uint32_t dpi)
|
||||
// - a size containing the requested dimensions in pixels.
|
||||
winrt::Windows::Foundation::Size TermControl::GetProposedDimensions(IControlSettings const& settings, const uint32_t dpi)
|
||||
{
|
||||
// If the settings have negative or zero row or column counts, ignore those counts.
|
||||
// (The lower TerminalCore layer also has upper bounds as well, but at this layer
|
||||
// we may eventually impose different ones depending on how many pixels we can address.)
|
||||
const auto cols = ::base::saturated_cast<float>(std::max(settings.InitialCols(), 1));
|
||||
const auto rows = ::base::saturated_cast<float>(std::max(settings.InitialRows(), 1));
|
||||
|
||||
const winrt::Windows::Foundation::Size initialSize{ cols, rows };
|
||||
|
||||
return GetProposedDimensions(initialSize,
|
||||
settings.FontSize(),
|
||||
settings.FontWeight(),
|
||||
settings.FontFace(),
|
||||
settings.ScrollState(),
|
||||
settings.Padding(),
|
||||
dpi);
|
||||
}
|
||||
|
||||
// Function Description:
|
||||
// - Determines how much space (in pixels) an app would need to reserve to
|
||||
// create a control with the settings stored in the settings param. This
|
||||
// accounts for things like the font size and face, the initialRows and
|
||||
// initialCols, and scrollbar visibility. The returned sized is based upon
|
||||
// the provided DPI value
|
||||
// Arguments:
|
||||
// - initialSizeInChars: The size to get the proposed dimensions for.
|
||||
// - fontHeight: The font height to use to calculate the proposed size for.
|
||||
// - fontWeight: The font weight to use to calculate the proposed size for.
|
||||
// - fontFace: The font name to use to calculate the proposed size for.
|
||||
// - scrollState: The ScrollbarState to use to calculate the proposed size for.
|
||||
// - padding: The padding to use to calculate the proposed size for.
|
||||
// - dpi: The DPI we should create the terminal at. This affects things such
|
||||
// as font size, scrollbar and other control scaling, etc. Make sure the
|
||||
// caller knows what monitor the control is about to appear on.
|
||||
// Return Value:
|
||||
// - a size containing the requested dimensions in pixels.
|
||||
winrt::Windows::Foundation::Size TermControl::GetProposedDimensions(const winrt::Windows::Foundation::Size& initialSizeInChars,
|
||||
const int32_t& fontHeight,
|
||||
const winrt::Windows::UI::Text::FontWeight& fontWeight,
|
||||
const winrt::hstring& fontFace,
|
||||
const Microsoft::Terminal::Settings::ScrollbarState& scrollState,
|
||||
const winrt::hstring& padding,
|
||||
const uint32_t dpi)
|
||||
{
|
||||
const auto cols = ::base::saturated_cast<int>(initialSizeInChars.Width);
|
||||
const auto rows = ::base::saturated_cast<int>(initialSizeInChars.Height);
|
||||
|
||||
// Initialize our font information.
|
||||
const auto fontFace = settings.FontFace();
|
||||
const short fontHeight = gsl::narrow_cast<short>(settings.FontSize());
|
||||
const auto fontWeight = settings.FontWeight();
|
||||
// const auto fontFace = settings.FontFace();
|
||||
// const short fontHeight = gsl::narrow_cast<short>(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, fontWeight.Weight, { 0, gsl::narrow_cast<short>(fontHeight) }, CP_UTF8, false };
|
||||
FontInfoDesired desiredFont = { actualFont };
|
||||
|
||||
// If the settings have negative or zero row or column counts, ignore those counts.
|
||||
// (The lower TerminalCore layer also has upper bounds as well, but at this layer
|
||||
// we may eventually impose different ones depending on how many pixels we can address.)
|
||||
const auto cols = std::max(settings.InitialCols(), 1);
|
||||
const auto rows = std::max(settings.InitialRows(), 1);
|
||||
|
||||
// Create a DX engine and initialize it with our font and DPI. We'll
|
||||
// then use it to measure how much space the requested rows and columns
|
||||
// will take up.
|
||||
@@ -2299,13 +2324,13 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
double width = cols * fontSize.X;
|
||||
|
||||
// Reserve additional space if scrollbar is intended to be visible
|
||||
if (settings.ScrollState() == ScrollbarState::Visible)
|
||||
if (scrollState == ScrollbarState::Visible)
|
||||
{
|
||||
width += scrollbarSize;
|
||||
}
|
||||
|
||||
double height = rows * fontSize.Y;
|
||||
auto thickness = _ParseThicknessFromPadding(settings.Padding());
|
||||
auto thickness = _ParseThicknessFromPadding(padding);
|
||||
// GH#2061 - make sure to account for the size the padding _will be_ scaled to
|
||||
width += scale * (thickness.Left + thickness.Right);
|
||||
height += scale * (thickness.Top + thickness.Bottom);
|
||||
@@ -2338,21 +2363,41 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
// have a visible character.
|
||||
winrt::Windows::Foundation::Size TermControl::MinimumSize()
|
||||
{
|
||||
const auto fontSize = _actualFont.GetSize();
|
||||
double width = fontSize.X;
|
||||
double height = fontSize.Y;
|
||||
// Reserve additional space if scrollbar is intended to be visible
|
||||
if (_settings.ScrollState() == ScrollbarState::Visible)
|
||||
if (_initializedTerminal)
|
||||
{
|
||||
width += ScrollBar().ActualWidth();
|
||||
const auto fontSize = _actualFont.GetSize();
|
||||
double width = fontSize.X;
|
||||
double height = fontSize.Y;
|
||||
// Reserve additional space if scrollbar is intended to be visible
|
||||
if (_settings.ScrollState() == ScrollbarState::Visible)
|
||||
{
|
||||
width += ScrollBar().ActualWidth();
|
||||
}
|
||||
|
||||
// Account for the size of any padding
|
||||
const auto padding = SwapChainPanel().Margin();
|
||||
width += padding.Left + padding.Right;
|
||||
height += padding.Top + padding.Bottom;
|
||||
|
||||
return { gsl::narrow_cast<float>(width), gsl::narrow_cast<float>(height) };
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the terminal hasn't been initialized yet, then the font size will
|
||||
// have dimensions {1, fontSize.Y}, which can mess with consumers of
|
||||
// this method. In that case, we'll need to pre-calculate the font
|
||||
// width, before we actually have a renderer or swapchain.
|
||||
const winrt::Windows::Foundation::Size minSize{ 1, 1 };
|
||||
const double scaleFactor = DisplayInformation::GetForCurrentView().RawPixelsPerViewPixel();
|
||||
const auto dpi = ::base::saturated_cast<uint32_t>(USER_DEFAULT_SCREEN_DPI * scaleFactor);
|
||||
return GetProposedDimensions(minSize,
|
||||
_settings.FontSize(),
|
||||
_settings.FontWeight(),
|
||||
_settings.FontFace(),
|
||||
_settings.ScrollState(),
|
||||
_settings.Padding(),
|
||||
dpi);
|
||||
}
|
||||
|
||||
// Account for the size of any padding
|
||||
const auto padding = GetPadding();
|
||||
width += padding.Left + padding.Right;
|
||||
height += padding.Top + padding.Bottom;
|
||||
|
||||
return { gsl::narrow_cast<float>(width), gsl::narrow_cast<float>(height) };
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -2368,7 +2413,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
const auto fontSize = _actualFont.GetSize();
|
||||
const auto fontDimension = widthOrHeight ? fontSize.X : fontSize.Y;
|
||||
|
||||
const auto padding = GetPadding();
|
||||
const auto padding = SwapChainPanel().Margin();
|
||||
auto nonTerminalArea = gsl::narrow_cast<float>(widthOrHeight ?
|
||||
padding.Left + padding.Right :
|
||||
padding.Top + padding.Bottom);
|
||||
@@ -2500,7 +2545,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
{
|
||||
// cursorPosition is DIPs, relative to SwapChainPanel origin
|
||||
const til::point cursorPosInDIPs{ til::math::rounding, cursorPosition };
|
||||
const til::size marginsInDips{ til::math::rounding, GetPadding().Left, GetPadding().Top };
|
||||
const til::size marginsInDips{ til::math::rounding, SwapChainPanel().Margin().Left, SwapChainPanel().Margin().Top };
|
||||
|
||||
// This point is the location of the cursor within the actual grid of characters, in DIPs
|
||||
const til::point relativeToMarginInDIPs = cursorPosInDIPs - marginsInDips;
|
||||
|
||||
@@ -78,8 +78,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
void AdjustFontSize(int fontSizeDelta);
|
||||
void ResetFontSize();
|
||||
|
||||
void ToggleRetroEffect();
|
||||
|
||||
winrt::fire_and_forget RenderEngineSwapChainChanged();
|
||||
void _AttachDxgiSwapChainToXaml(IDXGISwapChain1* swapChain);
|
||||
winrt::fire_and_forget _RendererEnteredErrorState();
|
||||
@@ -100,7 +98,14 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
|
||||
TerminalConnection::ConnectionState ConnectionState() const;
|
||||
|
||||
static Windows::Foundation::Point GetProposedDimensions(Microsoft::Terminal::Settings::IControlSettings const& settings, const uint32_t dpi);
|
||||
static Windows::Foundation::Size GetProposedDimensions(Microsoft::Terminal::Settings::IControlSettings const& settings, const uint32_t dpi);
|
||||
static Windows::Foundation::Size GetProposedDimensions(const winrt::Windows::Foundation::Size& initialSizeInChars,
|
||||
const int32_t& fontSize,
|
||||
const winrt::Windows::UI::Text::FontWeight& fontWeight,
|
||||
const winrt::hstring& fontFace,
|
||||
const Microsoft::Terminal::Settings::ScrollbarState& scrollState,
|
||||
const winrt::hstring& padding,
|
||||
const uint32_t dpi);
|
||||
|
||||
// clang-format off
|
||||
// -------------------------------- WinRT Events ---------------------------------
|
||||
@@ -213,7 +218,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
void _DoResizeUnderLock(const double newWidth, const double newHeight);
|
||||
void _RefreshSizeUnderLock();
|
||||
void _TerminalTitleChanged(const std::wstring_view& wstr);
|
||||
void _CopyToClipboard(const std::wstring_view& wstr);
|
||||
void _TerminalScrollPositionChanged(const int viewTop, const int viewHeight, const int bufferSize);
|
||||
void _TerminalCursorPositionChanged();
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace Microsoft.Terminal.TerminalControl
|
||||
TermControl();
|
||||
TermControl(Microsoft.Terminal.Settings.IControlSettings settings, Microsoft.Terminal.TerminalConnection.ITerminalConnection connection);
|
||||
|
||||
static Windows.Foundation.Point GetProposedDimensions(Microsoft.Terminal.Settings.IControlSettings settings, UInt32 dpi);
|
||||
static Windows.Foundation.Size GetProposedDimensions(Microsoft.Terminal.Settings.IControlSettings settings, UInt32 dpi);
|
||||
|
||||
void UpdateSettings(Microsoft.Terminal.Settings.IControlSettings newSettings);
|
||||
|
||||
@@ -68,7 +68,5 @@ namespace Microsoft.Terminal.TerminalControl
|
||||
|
||||
void AdjustFontSize(Int32 fontSizeDelta);
|
||||
void ResetFontSize();
|
||||
|
||||
void ToggleRetroEffect();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,16 +38,13 @@
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Grid Grid.Column="0"
|
||||
Visibility="Visible"
|
||||
Background="Transparent"
|
||||
PointerPressed="_PointerPressedHandler"
|
||||
PointerMoved="_PointerMovedHandler"
|
||||
PointerReleased="_PointerReleasedHandler">
|
||||
|
||||
<Grid Grid.Column="0">
|
||||
<SwapChainPanel x:Name="SwapChainPanel"
|
||||
SizeChanged="_SwapChainSizeChanged"
|
||||
CompositionScaleChanged="_SwapChainScaleChanged" />
|
||||
CompositionScaleChanged="_SwapChainScaleChanged"
|
||||
PointerPressed="_PointerPressedHandler"
|
||||
PointerMoved="_PointerMovedHandler"
|
||||
PointerReleased="_PointerReleasedHandler" />
|
||||
|
||||
<!-- Putting this in a grid w/ the SwapChainPanel
|
||||
ensures that it's always aligned w/ the scrollbar -->
|
||||
|
||||
@@ -29,7 +29,7 @@ ThrottledFunc<>::ThrottledFunc(ThrottledFunc::Func func, TimeSpan delay, CoreDis
|
||||
// - <none>
|
||||
void ThrottledFunc<>::Run()
|
||||
{
|
||||
if (_isRunPending.test_and_set(std::memory_order_acquire))
|
||||
if (_isRunPending.test_and_set())
|
||||
{
|
||||
// already pending
|
||||
return;
|
||||
@@ -44,7 +44,7 @@ void ThrottledFunc<>::Run()
|
||||
if (auto self{ weakThis.lock() })
|
||||
{
|
||||
timer.Stop();
|
||||
self->_isRunPending.clear(std::memory_order_release);
|
||||
self->_isRunPending.clear();
|
||||
self->_func();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../terminal/adapter/DispatchTypes.hpp"
|
||||
#include "../../buffer/out/TextAttribute.hpp"
|
||||
|
||||
namespace Microsoft::Terminal::Core
|
||||
{
|
||||
@@ -19,8 +18,15 @@ namespace Microsoft::Terminal::Core
|
||||
virtual bool PrintString(std::wstring_view string) noexcept = 0;
|
||||
virtual bool ExecuteChar(wchar_t wch) noexcept = 0;
|
||||
|
||||
virtual TextAttribute GetTextAttributes() const noexcept = 0;
|
||||
virtual void SetTextAttributes(const TextAttribute& attrs) noexcept = 0;
|
||||
virtual bool SetTextToDefaults(bool foreground, bool background) noexcept = 0;
|
||||
virtual bool SetTextForegroundIndex(BYTE colorIndex) noexcept = 0;
|
||||
virtual bool SetTextBackgroundIndex(BYTE colorIndex) noexcept = 0;
|
||||
virtual bool SetTextForegroundIndex256(BYTE colorIndex) noexcept = 0;
|
||||
virtual bool SetTextBackgroundIndex256(BYTE colorIndex) noexcept = 0;
|
||||
virtual bool SetTextRgbColor(COLORREF color, bool foreground) noexcept = 0;
|
||||
virtual bool BoldText(bool boldOn) noexcept = 0;
|
||||
virtual bool UnderlineText(bool underlineOn) noexcept = 0;
|
||||
virtual bool ReverseText(bool reversed) noexcept = 0;
|
||||
|
||||
virtual bool SetCursorPosition(short x, short y) noexcept = 0;
|
||||
virtual COORD GetCursorPosition() noexcept = 0;
|
||||
@@ -55,8 +61,6 @@ namespace Microsoft::Terminal::Core
|
||||
|
||||
virtual bool IsVtInputEnabled() const = 0;
|
||||
|
||||
virtual bool CopyToClipboard(std::wstring_view content) noexcept = 0;
|
||||
|
||||
protected:
|
||||
ITerminalApi() = default;
|
||||
};
|
||||
|
||||
@@ -891,11 +891,6 @@ void Terminal::SetTitleChangedCallback(std::function<void(const std::wstring_vie
|
||||
_pfnTitleChanged.swap(pfn);
|
||||
}
|
||||
|
||||
void Terminal::SetCopyToClipboardCallback(std::function<void(const std::wstring_view&)> pfn) noexcept
|
||||
{
|
||||
_pfnCopyToClipboard.swap(pfn);
|
||||
}
|
||||
|
||||
void Terminal::SetScrollPositionChangedCallback(std::function<void(const int, const int, const int)> pfn) noexcept
|
||||
{
|
||||
_pfnScrollPositionChanged.swap(pfn);
|
||||
|
||||
@@ -78,8 +78,15 @@ public:
|
||||
// These methods are defined in TerminalApi.cpp
|
||||
bool PrintString(std::wstring_view stringView) noexcept override;
|
||||
bool ExecuteChar(wchar_t wch) noexcept override;
|
||||
TextAttribute GetTextAttributes() const noexcept override;
|
||||
void SetTextAttributes(const TextAttribute& attrs) noexcept override;
|
||||
bool SetTextToDefaults(bool foreground, bool background) noexcept override;
|
||||
bool SetTextForegroundIndex(BYTE colorIndex) noexcept override;
|
||||
bool SetTextBackgroundIndex(BYTE colorIndex) noexcept override;
|
||||
bool SetTextForegroundIndex256(BYTE colorIndex) noexcept override;
|
||||
bool SetTextBackgroundIndex256(BYTE colorIndex) noexcept override;
|
||||
bool SetTextRgbColor(COLORREF color, bool foreground) noexcept override;
|
||||
bool BoldText(bool boldOn) noexcept override;
|
||||
bool UnderlineText(bool underlineOn) noexcept override;
|
||||
bool ReverseText(bool reversed) noexcept override;
|
||||
bool SetCursorPosition(short x, short y) noexcept override;
|
||||
COORD GetCursorPosition() noexcept override;
|
||||
bool SetCursorVisibility(const bool visible) noexcept override;
|
||||
@@ -107,8 +114,6 @@ public:
|
||||
bool EnableAlternateScrollMode(const bool enabled) noexcept override;
|
||||
|
||||
bool IsVtInputEnabled() const noexcept override;
|
||||
|
||||
bool CopyToClipboard(std::wstring_view content) noexcept override;
|
||||
#pragma endregion
|
||||
|
||||
#pragma region ITerminalInput
|
||||
@@ -167,7 +172,6 @@ public:
|
||||
|
||||
void SetWriteInputCallback(std::function<void(std::wstring&)> pfn) noexcept;
|
||||
void SetTitleChangedCallback(std::function<void(const std::wstring_view&)> pfn) noexcept;
|
||||
void SetCopyToClipboardCallback(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;
|
||||
@@ -194,7 +198,6 @@ public:
|
||||
private:
|
||||
std::function<void(std::wstring&)> _pfnWriteInput;
|
||||
std::function<void(const std::wstring_view&)> _pfnTitleChanged;
|
||||
std::function<void(const std::wstring_view&)> _pfnCopyToClipboard;
|
||||
std::function<void(const int, const int, const int)> _pfnScrollPositionChanged;
|
||||
std::function<void(const COLORREF)> _pfnBackgroundColorChanged;
|
||||
std::function<void()> _pfnCursorPositionChanged;
|
||||
|
||||
@@ -26,14 +26,83 @@ try
|
||||
}
|
||||
CATCH_LOG_RETURN_FALSE()
|
||||
|
||||
TextAttribute Terminal::GetTextAttributes() const noexcept
|
||||
bool Terminal::SetTextToDefaults(bool foreground, bool background) noexcept
|
||||
{
|
||||
return _buffer->GetCurrentAttributes();
|
||||
TextAttribute attrs = _buffer->GetCurrentAttributes();
|
||||
if (foreground)
|
||||
{
|
||||
attrs.SetDefaultForeground();
|
||||
}
|
||||
if (background)
|
||||
{
|
||||
attrs.SetDefaultBackground();
|
||||
}
|
||||
_buffer->SetCurrentAttributes(attrs);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Terminal::SetTextAttributes(const TextAttribute& attrs) noexcept
|
||||
bool Terminal::SetTextForegroundIndex(BYTE colorIndex) noexcept
|
||||
{
|
||||
TextAttribute attrs = _buffer->GetCurrentAttributes();
|
||||
attrs.SetIndexedForeground(colorIndex);
|
||||
_buffer->SetCurrentAttributes(attrs);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Terminal::SetTextBackgroundIndex(BYTE colorIndex) noexcept
|
||||
{
|
||||
TextAttribute attrs = _buffer->GetCurrentAttributes();
|
||||
attrs.SetIndexedBackground(colorIndex);
|
||||
_buffer->SetCurrentAttributes(attrs);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Terminal::SetTextForegroundIndex256(BYTE colorIndex) noexcept
|
||||
{
|
||||
TextAttribute attrs = _buffer->GetCurrentAttributes();
|
||||
attrs.SetIndexedForeground256(colorIndex);
|
||||
_buffer->SetCurrentAttributes(attrs);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Terminal::SetTextBackgroundIndex256(BYTE colorIndex) noexcept
|
||||
{
|
||||
TextAttribute attrs = _buffer->GetCurrentAttributes();
|
||||
attrs.SetIndexedBackground256(colorIndex);
|
||||
_buffer->SetCurrentAttributes(attrs);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Terminal::SetTextRgbColor(COLORREF color, bool foreground) noexcept
|
||||
{
|
||||
TextAttribute attrs = _buffer->GetCurrentAttributes();
|
||||
attrs.SetColor(color, foreground);
|
||||
_buffer->SetCurrentAttributes(attrs);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Terminal::BoldText(bool boldOn) noexcept
|
||||
{
|
||||
TextAttribute attrs = _buffer->GetCurrentAttributes();
|
||||
attrs.SetBold(boldOn);
|
||||
_buffer->SetCurrentAttributes(attrs);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Terminal::UnderlineText(bool underlineOn) noexcept
|
||||
{
|
||||
TextAttribute attrs = _buffer->GetCurrentAttributes();
|
||||
attrs.SetUnderline(underlineOn);
|
||||
_buffer->SetCurrentAttributes(attrs);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Terminal::ReverseText(bool reversed) noexcept
|
||||
{
|
||||
TextAttribute attrs = _buffer->GetCurrentAttributes();
|
||||
attrs.SetReverseVideo(reversed);
|
||||
_buffer->SetCurrentAttributes(attrs);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Terminal::SetCursorPosition(short x, short y) noexcept
|
||||
@@ -532,12 +601,3 @@ bool Terminal::EnableCursorBlinking(const bool enable) noexcept
|
||||
_buffer->GetCursor().SetIsOn(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Terminal::CopyToClipboard(std::wstring_view content) noexcept
|
||||
try
|
||||
{
|
||||
_pfnCopyToClipboard(content);
|
||||
|
||||
return true;
|
||||
}
|
||||
CATCH_LOG_RETURN_FALSE()
|
||||
|
||||
@@ -146,13 +146,6 @@ try
|
||||
}
|
||||
CATCH_LOG_RETURN_FALSE()
|
||||
|
||||
bool TerminalDispatch::SetClipboard(std::wstring_view content) noexcept
|
||||
try
|
||||
{
|
||||
return _terminalApi.CopyToClipboard(content);
|
||||
}
|
||||
CATCH_LOG_RETURN_FALSE()
|
||||
|
||||
// Method Description:
|
||||
// - Sets the default foreground color to a new value
|
||||
// Arguments:
|
||||
@@ -438,29 +431,44 @@ bool TerminalDispatch::SoftReset() noexcept
|
||||
// of what needs to be done.
|
||||
|
||||
bool success = CursorVisibility(true); // Cursor enabled.
|
||||
// success = SetOriginMode(false) && success; // Absolute cursor addressing.
|
||||
// success = SetAutoWrapMode(true) && success; // Wrap at end of line.
|
||||
success = SetCursorKeysMode(false) && success; // Normal characters.
|
||||
success = SetKeypadMode(false) && success; // Numeric characters.
|
||||
|
||||
// // Top margin = 1; bottom margin = page length.
|
||||
// success = _DoSetTopBottomScrollingMargins(0, 0) && success;
|
||||
|
||||
// _termOutput = {}; // Reset all character set designations.
|
||||
// if (_initialCodePage.has_value())
|
||||
// if (success)
|
||||
// {
|
||||
// // Restore initial code page if previously changed by a DOCS sequence.
|
||||
// success = _pConApi->SetConsoleOutputCP(_initialCodePage.value()) && success;
|
||||
// success = SetOriginMode(false); // Absolute cursor addressing.
|
||||
// }
|
||||
// if (success)
|
||||
// {
|
||||
// success = SetAutoWrapMode(true); // Wrap at end of line.
|
||||
// }
|
||||
if (success)
|
||||
{
|
||||
success = SetCursorKeysMode(false); // Normal characters.
|
||||
}
|
||||
if (success)
|
||||
{
|
||||
success = SetKeypadMode(false); // Numeric characters.
|
||||
}
|
||||
// if (success)
|
||||
// {
|
||||
// // Top margin = 1; bottom margin = page length.
|
||||
// success = _DoSetTopBottomScrollingMargins(0, 0);
|
||||
// }
|
||||
// if (success)
|
||||
// {
|
||||
// success = DesignateCharset(DispatchTypes::VTCharacterSets::USASCII); // Default Charset
|
||||
// }
|
||||
if (success)
|
||||
{
|
||||
const auto opt = DispatchTypes::GraphicsOptions::Off;
|
||||
success = SetGraphicsRendition({ &opt, 1 }); // Normal rendition.
|
||||
}
|
||||
// if (success)
|
||||
// {
|
||||
// // Reset the saved cursor state.
|
||||
// // Note that XTerm only resets the main buffer state, but that
|
||||
// // seems likely to be a bug. Most other terminals reset both.
|
||||
// _savedCursorState.at(0) = {}; // Main buffer
|
||||
// _savedCursorState.at(1) = {}; // Alt buffer
|
||||
// }
|
||||
|
||||
const auto opt = DispatchTypes::GraphicsOptions::Off;
|
||||
success = SetGraphicsRendition({ &opt, 1 }) && success; // Normal rendition.
|
||||
|
||||
// // Reset the saved cursor state.
|
||||
// // Note that XTerm only resets the main buffer state, but that
|
||||
// // seems likely to be a bug. Most other terminals reset both.
|
||||
// _savedCursorState.at(0) = {}; // Main buffer
|
||||
// _savedCursorState.at(1) = {}; // Alt buffer
|
||||
|
||||
return success;
|
||||
}
|
||||
@@ -476,31 +484,34 @@ bool TerminalDispatch::HardReset() noexcept
|
||||
// This code is left here (from its original form in conhost) as a reminder
|
||||
// of what needs to be done.
|
||||
|
||||
bool success = true;
|
||||
|
||||
// // If in the alt buffer, switch back to main before doing anything else.
|
||||
// if (_usingAltBuffer)
|
||||
// {
|
||||
// success = _pConApi->PrivateUseMainScreenBuffer();
|
||||
// _usingAltBuffer = !success;
|
||||
// }
|
||||
|
||||
// Sets the SGR state to normal - this must be done before EraseInDisplay
|
||||
// to ensure that it clears with the default background color.
|
||||
success = SoftReset() && success;
|
||||
bool success = SoftReset();
|
||||
|
||||
// Clears the screen - Needs to be done in two operations.
|
||||
success = EraseInDisplay(DispatchTypes::EraseType::All) && success;
|
||||
success = EraseInDisplay(DispatchTypes::EraseType::Scrollback) && success;
|
||||
if (success)
|
||||
{
|
||||
success = EraseInDisplay(DispatchTypes::EraseType::All);
|
||||
}
|
||||
if (success)
|
||||
{
|
||||
success = EraseInDisplay(DispatchTypes::EraseType::Scrollback);
|
||||
}
|
||||
|
||||
// // Set the DECSCNM screen mode back to normal.
|
||||
// success = SetScreenMode(false) && success;
|
||||
// if (success)
|
||||
// {
|
||||
// success = SetScreenMode(false);
|
||||
// }
|
||||
|
||||
// Cursor to 1,1 - the Soft Reset guarantees this is absolute
|
||||
success = CursorPosition(1, 1) && success;
|
||||
if (success)
|
||||
{
|
||||
success = CursorPosition(1, 1);
|
||||
}
|
||||
|
||||
// // Delete all current tab stops and reapply
|
||||
// _ResetTabStops();
|
||||
// // delete all current tab stops and reapply
|
||||
// _pConApi->PrivateSetDefaultTabStops();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -36,8 +36,6 @@ public:
|
||||
bool SetColorTableEntry(const size_t tableIndex, const DWORD color) noexcept override;
|
||||
bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) noexcept override;
|
||||
|
||||
bool SetClipboard(std::wstring_view content) noexcept override;
|
||||
|
||||
bool SetDefaultForeground(const DWORD color) noexcept override;
|
||||
bool SetDefaultBackground(const DWORD color) noexcept override;
|
||||
bool EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) noexcept override; // ED
|
||||
@@ -64,9 +62,11 @@ public:
|
||||
private:
|
||||
::Microsoft::Terminal::Core::ITerminalApi& _terminalApi;
|
||||
|
||||
size_t _SetRgbColorsHelper(const std::basic_string_view<::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions> options,
|
||||
TextAttribute& attr,
|
||||
const bool isForeground) noexcept;
|
||||
bool _SetRgbColorsHelper(const std::basic_string_view<::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions> options,
|
||||
size_t& optionsConsumed) noexcept;
|
||||
bool _SetBoldColorHelper(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions opt) noexcept;
|
||||
bool _SetDefaultColorHelper(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions opt) noexcept;
|
||||
void _SetGraphicsOptionHelper(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions opt) noexcept;
|
||||
|
||||
bool _SetResetPrivateModes(const std::basic_string_view<::Microsoft::Console::VirtualTerminal::DispatchTypes::PrivateModeParams> params, const bool enable) noexcept;
|
||||
bool _PrivateModeParamsHelper(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::PrivateModeParams param, const bool enable) noexcept;
|
||||
|
||||
@@ -3,23 +3,22 @@
|
||||
|
||||
#include "pch.h"
|
||||
#include "TerminalDispatch.hpp"
|
||||
|
||||
using namespace Microsoft::Console::VirtualTerminal;
|
||||
using namespace Microsoft::Console::VirtualTerminal::DispatchTypes;
|
||||
using namespace ::Microsoft::Terminal::Core;
|
||||
using namespace ::Microsoft::Console::VirtualTerminal;
|
||||
|
||||
// clang-format off
|
||||
const BYTE RED_ATTR = 0x01;
|
||||
const BYTE GREEN_ATTR = 0x02;
|
||||
const BYTE BLUE_ATTR = 0x04;
|
||||
const BYTE BRIGHT_ATTR = 0x08;
|
||||
const BYTE DARK_BLACK = 0;
|
||||
const BYTE DARK_RED = RED_ATTR;
|
||||
const BYTE DARK_GREEN = GREEN_ATTR;
|
||||
const BYTE DARK_YELLOW = RED_ATTR | GREEN_ATTR;
|
||||
const BYTE DARK_BLUE = BLUE_ATTR;
|
||||
const BYTE DARK_MAGENTA = RED_ATTR | BLUE_ATTR;
|
||||
const BYTE DARK_CYAN = GREEN_ATTR | BLUE_ATTR;
|
||||
const BYTE DARK_WHITE = RED_ATTR | GREEN_ATTR | BLUE_ATTR;
|
||||
const BYTE RED_ATTR = 0x01;
|
||||
const BYTE GREEN_ATTR = 0x02;
|
||||
const BYTE BLUE_ATTR = 0x04;
|
||||
const BYTE BRIGHT_ATTR = 0x08;
|
||||
const BYTE DARK_BLACK = 0;
|
||||
const BYTE DARK_RED = RED_ATTR;
|
||||
const BYTE DARK_GREEN = GREEN_ATTR;
|
||||
const BYTE DARK_YELLOW = RED_ATTR | GREEN_ATTR;
|
||||
const BYTE DARK_BLUE = BLUE_ATTR;
|
||||
const BYTE DARK_MAGENTA = RED_ATTR | BLUE_ATTR;
|
||||
const BYTE DARK_CYAN = GREEN_ATTR | BLUE_ATTR;
|
||||
const BYTE DARK_WHITE = RED_ATTR | GREEN_ATTR | BLUE_ATTR;
|
||||
const BYTE BRIGHT_BLACK = BRIGHT_ATTR;
|
||||
const BYTE BRIGHT_RED = BRIGHT_ATTR | RED_ATTR;
|
||||
const BYTE BRIGHT_GREEN = BRIGHT_ATTR | GREEN_ATTR;
|
||||
@@ -30,6 +29,40 @@ const BYTE BRIGHT_CYAN = BRIGHT_ATTR | GREEN_ATTR | BLUE_ATTR;
|
||||
const BYTE BRIGHT_WHITE = BRIGHT_ATTR | RED_ATTR | GREEN_ATTR | BLUE_ATTR;
|
||||
// clang-format on
|
||||
|
||||
// Routine Description:
|
||||
// Returns true if the GraphicsOption represents an extended color option.
|
||||
// These are followed by up to 4 more values which compose the entire option.
|
||||
// Return Value:
|
||||
// - true if the opt is the indicator for an extended color sequence, false otherwise.
|
||||
static constexpr bool _isRgbColorOption(const DispatchTypes::GraphicsOptions opt) noexcept
|
||||
{
|
||||
return opt == DispatchTypes::GraphicsOptions::ForegroundExtended ||
|
||||
opt == DispatchTypes::GraphicsOptions::BackgroundExtended;
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// Returns true if the GraphicsOption represents an extended color option.
|
||||
// These are followed by up to 4 more values which compose the entire option.
|
||||
// Return Value:
|
||||
// - true if the opt is the indicator for an extended color sequence, false otherwise.
|
||||
static constexpr bool _isBoldColorOption(const DispatchTypes::GraphicsOptions opt) noexcept
|
||||
{
|
||||
return opt == DispatchTypes::GraphicsOptions::BoldBright ||
|
||||
opt == DispatchTypes::GraphicsOptions::UnBold;
|
||||
}
|
||||
|
||||
// Function Description:
|
||||
// - checks if this graphics option should set either the console's FG or BG to
|
||||
//the default attributes.
|
||||
// Return Value:
|
||||
// - true if the opt sets either/or attribute to the defaults, false otherwise.
|
||||
static constexpr bool _isDefaultColorOption(const DispatchTypes::GraphicsOptions opt) noexcept
|
||||
{
|
||||
return opt == DispatchTypes::GraphicsOptions::Off ||
|
||||
opt == DispatchTypes::GraphicsOptions::ForegroundDefault ||
|
||||
opt == DispatchTypes::GraphicsOptions::BackgroundDefault;
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - Helper to parse extended graphics options, which start with 38 (FG) or 48 (BG)
|
||||
// These options are followed by either a 2 (RGB) or 5 (xterm index)
|
||||
@@ -37,237 +70,257 @@ const BYTE BRIGHT_WHITE = BRIGHT_ATTR | RED_ATTR | GREEN_ATTR | BLUE_ATTR;
|
||||
// Xterm index will use the param that follows to use a color from the preset 256 color xterm color table.
|
||||
// Arguments:
|
||||
// - options - An array of options that will be used to generate the RGB color
|
||||
// - attr - The attribute that will be updated with the parsed color.
|
||||
// - isForeground - Whether or not the parsed color is for the foreground.
|
||||
// - optionsConsumed - Returns the number of options we consumed parsing this option.
|
||||
// Return Value:
|
||||
// - The number of options consumed, not including the initial 38/48.
|
||||
size_t TerminalDispatch::_SetRgbColorsHelper(const std::basic_string_view<DispatchTypes::GraphicsOptions> options,
|
||||
TextAttribute& attr,
|
||||
const bool isForeground) noexcept
|
||||
// Returns true if we successfully parsed an extended color option from the options array.
|
||||
// - This corresponds to the following number of options consumed (pcOptionsConsumed):
|
||||
// 1 - false, not enough options to parse.
|
||||
// 2 - false, not enough options to parse.
|
||||
// 3 - true, parsed an xterm index to a color
|
||||
// 5 - true, parsed an RGB color.
|
||||
bool TerminalDispatch::_SetRgbColorsHelper(const std::basic_string_view<DispatchTypes::GraphicsOptions> options,
|
||||
size_t& optionsConsumed) noexcept
|
||||
{
|
||||
size_t optionsConsumed = 0;
|
||||
if (options.size() >= 1)
|
||||
COLORREF color = 0;
|
||||
bool isForeground = false;
|
||||
|
||||
bool success = false;
|
||||
optionsConsumed = 1;
|
||||
if (options.size() >= 2 && _isRgbColorOption(options.front()))
|
||||
{
|
||||
optionsConsumed = 1;
|
||||
const auto typeOpt = til::at(options, 0);
|
||||
if (typeOpt == DispatchTypes::GraphicsOptions::RGBColorOrFaint && options.size() >= 4)
|
||||
optionsConsumed = 2;
|
||||
const auto extendedOpt = til::at(options, 0);
|
||||
const auto typeOpt = til::at(options, 1);
|
||||
|
||||
if (extendedOpt == DispatchTypes::GraphicsOptions::ForegroundExtended)
|
||||
{
|
||||
optionsConsumed = 4;
|
||||
const size_t red = til::at(options, 1);
|
||||
const size_t green = til::at(options, 2);
|
||||
const size_t blue = til::at(options, 3);
|
||||
// ensure that each value fits in a byte
|
||||
if (red <= 255 && green <= 255 && blue <= 255)
|
||||
{
|
||||
const COLORREF rgbColor = RGB(red, green, blue);
|
||||
attr.SetColor(rgbColor, isForeground);
|
||||
}
|
||||
isForeground = true;
|
||||
}
|
||||
else if (typeOpt == DispatchTypes::GraphicsOptions::BlinkOrXterm256Index && options.size() >= 2)
|
||||
else if (extendedOpt == DispatchTypes::GraphicsOptions::BackgroundExtended)
|
||||
{
|
||||
optionsConsumed = 2;
|
||||
const size_t tableIndex = til::at(options, 1);
|
||||
if (tableIndex <= 255)
|
||||
isForeground = false;
|
||||
}
|
||||
|
||||
if (typeOpt == DispatchTypes::GraphicsOptions::RGBColorOrFaint && options.size() >= 5)
|
||||
{
|
||||
optionsConsumed = 5;
|
||||
// ensure that each value fits in a byte
|
||||
const auto limit = static_cast<DispatchTypes::GraphicsOptions>(255);
|
||||
const auto red = std::min(options.at(2), limit);
|
||||
const auto green = std::min(options.at(3), limit);
|
||||
const auto blue = std::min(options.at(4), limit);
|
||||
|
||||
color = RGB(red, green, blue);
|
||||
|
||||
success = _terminalApi.SetTextRgbColor(color, isForeground);
|
||||
}
|
||||
else if (typeOpt == DispatchTypes::GraphicsOptions::BlinkOrXterm256Index && options.size() >= 3)
|
||||
{
|
||||
optionsConsumed = 3;
|
||||
if (options.at(2) <= 255) // ensure that the provided index is on the table
|
||||
{
|
||||
const auto adjustedIndex = gsl::narrow_cast<BYTE>(tableIndex);
|
||||
if (isForeground)
|
||||
{
|
||||
attr.SetIndexedForeground256(adjustedIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
attr.SetIndexedBackground256(adjustedIndex);
|
||||
}
|
||||
const auto tableIndex = til::at(options, 2);
|
||||
success = isForeground ?
|
||||
_terminalApi.SetTextForegroundIndex256(gsl::narrow_cast<BYTE>(tableIndex)) :
|
||||
_terminalApi.SetTextBackgroundIndex256(gsl::narrow_cast<BYTE>(tableIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
return optionsConsumed;
|
||||
return success;
|
||||
}
|
||||
|
||||
bool TerminalDispatch::_SetBoldColorHelper(const DispatchTypes::GraphicsOptions option) noexcept
|
||||
{
|
||||
const bool bold = (option == DispatchTypes::GraphicsOptions::BoldBright);
|
||||
return _terminalApi.BoldText(bold);
|
||||
}
|
||||
|
||||
bool TerminalDispatch::_SetDefaultColorHelper(const DispatchTypes::GraphicsOptions option) noexcept
|
||||
{
|
||||
const bool fg = option == DispatchTypes::GraphicsOptions::Off || option == DispatchTypes::GraphicsOptions::ForegroundDefault;
|
||||
const bool bg = option == DispatchTypes::GraphicsOptions::Off || option == DispatchTypes::GraphicsOptions::BackgroundDefault;
|
||||
bool success = _terminalApi.SetTextToDefaults(fg, bg);
|
||||
|
||||
if (success && fg && bg)
|
||||
{
|
||||
// If we're resetting both the FG & BG, also reset the meta attributes (underline)
|
||||
// as well as the boldness
|
||||
success = _terminalApi.UnderlineText(false) &&
|
||||
_terminalApi.ReverseText(false) &&
|
||||
_terminalApi.BoldText(false);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - SGR - Modifies the graphical rendering options applied to the next
|
||||
// characters written into the buffer.
|
||||
// - Options include colors, invert, underlines, and other "font style"
|
||||
// type options.
|
||||
// - Helper to apply the actual flags to each text attributes field.
|
||||
// - Placed as a helper so it can be recursive/re-entrant for some of the convenience flag methods that perform similar/multiple operations in one command.
|
||||
// Arguments:
|
||||
// - options - An array of options that will be applied from 0 to N, in order,
|
||||
// one at a time by setting or removing flags in the font style properties.
|
||||
// - opt - Graphics option sent to us by the parser/requestor.
|
||||
// - pAttr - Pointer to the font attribute field to adjust
|
||||
// Return Value:
|
||||
// - True if handled successfully. False otherwise.
|
||||
// - <none>
|
||||
void TerminalDispatch::_SetGraphicsOptionHelper(const DispatchTypes::GraphicsOptions opt) noexcept
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case DispatchTypes::GraphicsOptions::Off:
|
||||
FAIL_FAST_MSG("GraphicsOptions::Off should be handled by _SetDefaultColorHelper");
|
||||
break;
|
||||
// MSFT:16398982 - These two are now handled by _SetBoldColorHelper
|
||||
// case DispatchTypes::GraphicsOptions::BoldBright:
|
||||
// case DispatchTypes::GraphicsOptions::UnBold:
|
||||
case DispatchTypes::GraphicsOptions::Negative:
|
||||
_terminalApi.ReverseText(true);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::Underline:
|
||||
_terminalApi.UnderlineText(true);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::Positive:
|
||||
_terminalApi.ReverseText(false);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::NoUnderline:
|
||||
_terminalApi.UnderlineText(false);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::ForegroundBlack:
|
||||
_terminalApi.SetTextForegroundIndex(DARK_BLACK);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::ForegroundBlue:
|
||||
_terminalApi.SetTextForegroundIndex(DARK_BLUE);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::ForegroundGreen:
|
||||
_terminalApi.SetTextForegroundIndex(DARK_GREEN);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::ForegroundCyan:
|
||||
_terminalApi.SetTextForegroundIndex(DARK_CYAN);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::ForegroundRed:
|
||||
_terminalApi.SetTextForegroundIndex(DARK_RED);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::ForegroundMagenta:
|
||||
_terminalApi.SetTextForegroundIndex(DARK_MAGENTA);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::ForegroundYellow:
|
||||
_terminalApi.SetTextForegroundIndex(DARK_YELLOW);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::ForegroundWhite:
|
||||
_terminalApi.SetTextForegroundIndex(DARK_WHITE);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::ForegroundDefault:
|
||||
FAIL_FAST_MSG("GraphicsOptions::ForegroundDefault should be handled by _SetDefaultColorHelper");
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::BackgroundBlack:
|
||||
_terminalApi.SetTextBackgroundIndex(DARK_BLACK);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::BackgroundBlue:
|
||||
_terminalApi.SetTextBackgroundIndex(DARK_BLUE);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::BackgroundGreen:
|
||||
_terminalApi.SetTextBackgroundIndex(DARK_GREEN);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::BackgroundCyan:
|
||||
_terminalApi.SetTextBackgroundIndex(DARK_CYAN);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::BackgroundRed:
|
||||
_terminalApi.SetTextBackgroundIndex(DARK_RED);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::BackgroundMagenta:
|
||||
_terminalApi.SetTextBackgroundIndex(DARK_MAGENTA);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::BackgroundYellow:
|
||||
_terminalApi.SetTextBackgroundIndex(DARK_YELLOW);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::BackgroundWhite:
|
||||
_terminalApi.SetTextBackgroundIndex(DARK_WHITE);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::BackgroundDefault:
|
||||
FAIL_FAST_MSG("GraphicsOptions::BackgroundDefault should be handled by _SetDefaultColorHelper");
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::BrightForegroundBlack:
|
||||
_terminalApi.SetTextForegroundIndex(BRIGHT_BLACK);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::BrightForegroundBlue:
|
||||
_terminalApi.SetTextForegroundIndex(BRIGHT_BLUE);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::BrightForegroundGreen:
|
||||
_terminalApi.SetTextForegroundIndex(BRIGHT_GREEN);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::BrightForegroundCyan:
|
||||
_terminalApi.SetTextForegroundIndex(BRIGHT_CYAN);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::BrightForegroundRed:
|
||||
_terminalApi.SetTextForegroundIndex(BRIGHT_RED);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::BrightForegroundMagenta:
|
||||
_terminalApi.SetTextForegroundIndex(BRIGHT_MAGENTA);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::BrightForegroundYellow:
|
||||
_terminalApi.SetTextForegroundIndex(BRIGHT_YELLOW);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::BrightForegroundWhite:
|
||||
_terminalApi.SetTextForegroundIndex(BRIGHT_WHITE);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::BrightBackgroundBlack:
|
||||
_terminalApi.SetTextBackgroundIndex(BRIGHT_BLACK);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::BrightBackgroundBlue:
|
||||
_terminalApi.SetTextBackgroundIndex(BRIGHT_BLUE);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::BrightBackgroundGreen:
|
||||
_terminalApi.SetTextBackgroundIndex(BRIGHT_GREEN);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::BrightBackgroundCyan:
|
||||
_terminalApi.SetTextBackgroundIndex(BRIGHT_CYAN);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::BrightBackgroundRed:
|
||||
_terminalApi.SetTextBackgroundIndex(BRIGHT_RED);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::BrightBackgroundMagenta:
|
||||
_terminalApi.SetTextBackgroundIndex(BRIGHT_MAGENTA);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::BrightBackgroundYellow:
|
||||
_terminalApi.SetTextBackgroundIndex(BRIGHT_YELLOW);
|
||||
break;
|
||||
case DispatchTypes::GraphicsOptions::BrightBackgroundWhite:
|
||||
_terminalApi.SetTextBackgroundIndex(BRIGHT_WHITE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool TerminalDispatch::SetGraphicsRendition(const std::basic_string_view<DispatchTypes::GraphicsOptions> options) noexcept
|
||||
{
|
||||
TextAttribute attr = _terminalApi.GetTextAttributes();
|
||||
|
||||
bool success = false;
|
||||
// Run through the graphics options and apply them
|
||||
for (size_t i = 0; i < options.size(); i++)
|
||||
{
|
||||
const auto opt = til::at(options, i);
|
||||
switch (opt)
|
||||
const auto opt = options.at(i);
|
||||
if (_isDefaultColorOption(opt))
|
||||
{
|
||||
case Off:
|
||||
attr.SetDefaultForeground();
|
||||
attr.SetDefaultBackground();
|
||||
attr.SetStandardErase();
|
||||
break;
|
||||
case ForegroundDefault:
|
||||
attr.SetDefaultForeground();
|
||||
break;
|
||||
case BackgroundDefault:
|
||||
attr.SetDefaultBackground();
|
||||
break;
|
||||
case BoldBright:
|
||||
attr.SetBold(true);
|
||||
break;
|
||||
case UnBold:
|
||||
attr.SetBold(false);
|
||||
break;
|
||||
case Italics:
|
||||
attr.SetItalics(true);
|
||||
break;
|
||||
case NotItalics:
|
||||
attr.SetItalics(false);
|
||||
break;
|
||||
case BlinkOrXterm256Index:
|
||||
attr.SetBlinking(true);
|
||||
break;
|
||||
case Steady:
|
||||
attr.SetBlinking(false);
|
||||
break;
|
||||
case Invisible:
|
||||
attr.SetInvisible(true);
|
||||
break;
|
||||
case Visible:
|
||||
attr.SetInvisible(false);
|
||||
break;
|
||||
case CrossedOut:
|
||||
attr.SetCrossedOut(true);
|
||||
break;
|
||||
case NotCrossedOut:
|
||||
attr.SetCrossedOut(false);
|
||||
break;
|
||||
case Negative:
|
||||
attr.SetReverseVideo(true);
|
||||
break;
|
||||
case Positive:
|
||||
attr.SetReverseVideo(false);
|
||||
break;
|
||||
case Underline:
|
||||
attr.SetUnderline(true);
|
||||
break;
|
||||
case NoUnderline:
|
||||
attr.SetUnderline(false);
|
||||
break;
|
||||
case Overline:
|
||||
attr.SetOverline(true);
|
||||
break;
|
||||
case NoOverline:
|
||||
attr.SetOverline(false);
|
||||
break;
|
||||
case ForegroundBlack:
|
||||
attr.SetIndexedForeground(DARK_BLACK);
|
||||
break;
|
||||
case ForegroundBlue:
|
||||
attr.SetIndexedForeground(DARK_BLUE);
|
||||
break;
|
||||
case ForegroundGreen:
|
||||
attr.SetIndexedForeground(DARK_GREEN);
|
||||
break;
|
||||
case ForegroundCyan:
|
||||
attr.SetIndexedForeground(DARK_CYAN);
|
||||
break;
|
||||
case ForegroundRed:
|
||||
attr.SetIndexedForeground(DARK_RED);
|
||||
break;
|
||||
case ForegroundMagenta:
|
||||
attr.SetIndexedForeground(DARK_MAGENTA);
|
||||
break;
|
||||
case ForegroundYellow:
|
||||
attr.SetIndexedForeground(DARK_YELLOW);
|
||||
break;
|
||||
case ForegroundWhite:
|
||||
attr.SetIndexedForeground(DARK_WHITE);
|
||||
break;
|
||||
case BackgroundBlack:
|
||||
attr.SetIndexedBackground(DARK_BLACK);
|
||||
break;
|
||||
case BackgroundBlue:
|
||||
attr.SetIndexedBackground(DARK_BLUE);
|
||||
break;
|
||||
case BackgroundGreen:
|
||||
attr.SetIndexedBackground(DARK_GREEN);
|
||||
break;
|
||||
case BackgroundCyan:
|
||||
attr.SetIndexedBackground(DARK_CYAN);
|
||||
break;
|
||||
case BackgroundRed:
|
||||
attr.SetIndexedBackground(DARK_RED);
|
||||
break;
|
||||
case BackgroundMagenta:
|
||||
attr.SetIndexedBackground(DARK_MAGENTA);
|
||||
break;
|
||||
case BackgroundYellow:
|
||||
attr.SetIndexedBackground(DARK_YELLOW);
|
||||
break;
|
||||
case BackgroundWhite:
|
||||
attr.SetIndexedBackground(DARK_WHITE);
|
||||
break;
|
||||
case BrightForegroundBlack:
|
||||
attr.SetIndexedForeground(BRIGHT_BLACK);
|
||||
break;
|
||||
case BrightForegroundBlue:
|
||||
attr.SetIndexedForeground(BRIGHT_BLUE);
|
||||
break;
|
||||
case BrightForegroundGreen:
|
||||
attr.SetIndexedForeground(BRIGHT_GREEN);
|
||||
break;
|
||||
case BrightForegroundCyan:
|
||||
attr.SetIndexedForeground(BRIGHT_CYAN);
|
||||
break;
|
||||
case BrightForegroundRed:
|
||||
attr.SetIndexedForeground(BRIGHT_RED);
|
||||
break;
|
||||
case BrightForegroundMagenta:
|
||||
attr.SetIndexedForeground(BRIGHT_MAGENTA);
|
||||
break;
|
||||
case BrightForegroundYellow:
|
||||
attr.SetIndexedForeground(BRIGHT_YELLOW);
|
||||
break;
|
||||
case BrightForegroundWhite:
|
||||
attr.SetIndexedForeground(BRIGHT_WHITE);
|
||||
break;
|
||||
case BrightBackgroundBlack:
|
||||
attr.SetIndexedBackground(BRIGHT_BLACK);
|
||||
break;
|
||||
case BrightBackgroundBlue:
|
||||
attr.SetIndexedBackground(BRIGHT_BLUE);
|
||||
break;
|
||||
case BrightBackgroundGreen:
|
||||
attr.SetIndexedBackground(BRIGHT_GREEN);
|
||||
break;
|
||||
case BrightBackgroundCyan:
|
||||
attr.SetIndexedBackground(BRIGHT_CYAN);
|
||||
break;
|
||||
case BrightBackgroundRed:
|
||||
attr.SetIndexedBackground(BRIGHT_RED);
|
||||
break;
|
||||
case BrightBackgroundMagenta:
|
||||
attr.SetIndexedBackground(BRIGHT_MAGENTA);
|
||||
break;
|
||||
case BrightBackgroundYellow:
|
||||
attr.SetIndexedBackground(BRIGHT_YELLOW);
|
||||
break;
|
||||
case BrightBackgroundWhite:
|
||||
attr.SetIndexedBackground(BRIGHT_WHITE);
|
||||
break;
|
||||
case ForegroundExtended:
|
||||
i += _SetRgbColorsHelper(options.substr(i + 1), attr, true);
|
||||
break;
|
||||
case BackgroundExtended:
|
||||
i += _SetRgbColorsHelper(options.substr(i + 1), attr, false);
|
||||
break;
|
||||
success = _SetDefaultColorHelper(opt);
|
||||
}
|
||||
else if (_isBoldColorOption(opt))
|
||||
{
|
||||
success = _SetBoldColorHelper(opt);
|
||||
}
|
||||
else if (_isRgbColorOption(opt))
|
||||
{
|
||||
size_t optionsConsumed = 0;
|
||||
|
||||
// _SetRgbColorsHelper will call the appropriate ConApi function
|
||||
success = _SetRgbColorsHelper(options.substr(i), optionsConsumed);
|
||||
|
||||
i += (optionsConsumed - 1); // optionsConsumed includes the opt we're currently on.
|
||||
}
|
||||
else
|
||||
{
|
||||
_SetGraphicsOptionHelper(opt);
|
||||
|
||||
// Make sure we un-bold
|
||||
if (success && opt == DispatchTypes::GraphicsOptions::Off)
|
||||
{
|
||||
success = _SetBoldColorHelper(opt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_terminalApi.SetTextAttributes(attr);
|
||||
return true;
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -116,7 +116,9 @@ class TerminalCoreUnitTests::ConptyRoundtripTests final
|
||||
Viewport initialViewport = currentBuffer.GetViewport();
|
||||
|
||||
auto vtRenderEngine = std::make_unique<Xterm256Engine>(std::move(hFile),
|
||||
initialViewport);
|
||||
gci,
|
||||
initialViewport,
|
||||
gci.Get16ColorTable());
|
||||
auto pfn = std::bind(&ConptyRoundtripTests::_writeCallback, this, std::placeholders::_1, std::placeholders::_2);
|
||||
vtRenderEngine->SetTestCallback(pfn);
|
||||
|
||||
|
||||
@@ -283,9 +283,9 @@ void AppHost::_HandleCreateWindow(const HWND hwnd, RECT proposedRect, winrt::Ter
|
||||
auto initialSize = _logic.GetLaunchDimensions(dpix);
|
||||
|
||||
const short islandWidth = Utils::ClampToShortMax(
|
||||
static_cast<long>(ceil(initialSize.X)), 1);
|
||||
static_cast<long>(ceil(initialSize.Width)), 1);
|
||||
const short islandHeight = Utils::ClampToShortMax(
|
||||
static_cast<long>(ceil(initialSize.Y)), 1);
|
||||
static_cast<long>(ceil(initialSize.Height)), 1);
|
||||
|
||||
// Get the size of a window we'd need to host that client rect. This will
|
||||
// add the titlebar space.
|
||||
|
||||
@@ -99,14 +99,14 @@
|
||||
|
||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
|
||||
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.4.2-prerelease.200604001\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.4.2-prerelease.200604001\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.1-rc\build\native\Microsoft.VCRTForwarders.140.targets" Condition="Exists('..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.1-rc\build\native\Microsoft.VCRTForwarders.140.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.4.2-prerelease.200604001\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.4.2-prerelease.200604001\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.1-rc\build\native\Microsoft.VCRTForwarders.140.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.1-rc\build\native\Microsoft.VCRTForwarders.140.targets'))" />
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.200316.3" targetFramework="native" />
|
||||
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.0.0" targetFramework="native" />
|
||||
<package id="Microsoft.UI.Xaml" version="2.5.0-prerelease.200609001" targetFramework="native" />
|
||||
<package id="Microsoft.UI.Xaml" version="2.4.2-prerelease.200604001" targetFramework="native" />
|
||||
<package id="Microsoft.VCRTForwarders.140" version="1.0.1-rc" targetFramework="native" />
|
||||
<package id="Terminal.ThemeHelpers" version="0.2.200324001" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -25,8 +25,8 @@ Abstract:
|
||||
|
||||
#include <windows.h>
|
||||
#include <UIAutomation.h>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <shellscalingapi.h>
|
||||
#include <windowsx.h>
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.4.2-prerelease.200604001\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.4.2-prerelease.200604001\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
|
||||
</ImportGroup>
|
||||
@@ -168,7 +168,7 @@
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.4.2-prerelease.200604001\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.4.2-prerelease.200604001\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props'))" />
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
<!-- From Microsoft.UI.Xaml.targets -->
|
||||
<Native-Platform Condition="'$(Platform)' == 'Win32'">x86</Native-Platform>
|
||||
<Native-Platform Condition="'$(Platform)' != 'Win32'">$(Platform)</Native-Platform>
|
||||
<_MUXBinRoot>"$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\runtimes\win10-$(Native-Platform)\native\"</_MUXBinRoot>
|
||||
<_MUXBinRoot>"$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.4.2-prerelease.200604001\runtimes\win10-$(Native-Platform)\native\"</_MUXBinRoot>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
|
||||
@@ -155,16 +155,22 @@ VtIo::VtIo() :
|
||||
{
|
||||
case VtIoMode::XTERM_256:
|
||||
_pVtRenderEngine = std::make_unique<Xterm256Engine>(std::move(_hOutput),
|
||||
initialViewport);
|
||||
gci,
|
||||
initialViewport,
|
||||
gci.Get16ColorTable());
|
||||
break;
|
||||
case VtIoMode::XTERM:
|
||||
_pVtRenderEngine = std::make_unique<XtermEngine>(std::move(_hOutput),
|
||||
gci,
|
||||
initialViewport,
|
||||
gci.Get16ColorTable(),
|
||||
false);
|
||||
break;
|
||||
case VtIoMode::XTERM_ASCII:
|
||||
_pVtRenderEngine = std::make_unique<XtermEngine>(std::move(_hOutput),
|
||||
gci,
|
||||
initialViewport,
|
||||
gci.Get16ColorTable(),
|
||||
true);
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -1062,10 +1062,10 @@ constexpr unsigned int LOCAL_BUFFER_SIZE = 100;
|
||||
// - S_OK if successful.
|
||||
// - S_OK if we need to wait (check if ppWaiter is not nullptr).
|
||||
// - Or a suitable HRESULT code for math/string/memory failures.
|
||||
[[nodiscard]] HRESULT WriteConsoleAImplForReals(IConsoleOutputObject& context,
|
||||
const std::string_view buffer,
|
||||
size_t& read,
|
||||
std::unique_ptr<IWaitRoutine>& waiter) noexcept
|
||||
[[nodiscard]] HRESULT ApiRoutines::WriteConsoleAImpl(IConsoleOutputObject& context,
|
||||
const std::string_view buffer,
|
||||
size_t& read,
|
||||
std::unique_ptr<IWaitRoutine>& waiter) noexcept
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -1238,50 +1238,6 @@ constexpr unsigned int LOCAL_BUFFER_SIZE = 100;
|
||||
CATCH_RETURN();
|
||||
}
|
||||
|
||||
static auto channelpair = til::spsc::channel<char>(16* 1024);
|
||||
static IConsoleOutputObject* obj = nullptr;
|
||||
static void ioWriteConsoleMethod()
|
||||
{
|
||||
size_t read = 0;
|
||||
std::unique_ptr<IWaitRoutine> wait;
|
||||
|
||||
std::vector<char> buf(16 * 1024, '\0');
|
||||
|
||||
while (true)
|
||||
{
|
||||
auto [count, ok] = channelpair.second.pop_n(til::spsc::block_initially, buf.data(), buf.size());
|
||||
if (!ok)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
LOG_IF_FAILED(WriteConsoleAImplForReals(*obj, std::string_view{ buf.data(), count }, read, wait));
|
||||
}
|
||||
}
|
||||
|
||||
static std::thread th(ioWriteConsoleMethod);
|
||||
|
||||
[[nodiscard]] HRESULT ApiRoutines::WriteConsoleAImpl(IConsoleOutputObject& context,
|
||||
const std::string_view buffer,
|
||||
size_t& read,
|
||||
std::unique_ptr<IWaitRoutine>& waiter) noexcept
|
||||
try
|
||||
{
|
||||
read = buffer.size();
|
||||
waiter.reset();
|
||||
|
||||
if (!obj)
|
||||
{
|
||||
obj = &context;
|
||||
}
|
||||
|
||||
channelpair.first.push_n(buffer.data(), buffer.size());
|
||||
|
||||
return S_OK;
|
||||
//return WriteConsoleAImplForReals(context, buffer, read, waiter);
|
||||
}
|
||||
CATCH_RETURN()
|
||||
|
||||
// Routine Description:
|
||||
// - Writes Unicode formatted data into the given console output object.
|
||||
// - NOTE: This may be blocked for various console states and will return a wait context pointer if necessary.
|
||||
|
||||
@@ -15,7 +15,101 @@ Author(s):
|
||||
|
||||
#include "precomp.h"
|
||||
#include "..\inc\conattrs.hpp"
|
||||
#include <cmath>
|
||||
#include <math.h>
|
||||
|
||||
struct _HSL
|
||||
{
|
||||
double h, s, l;
|
||||
|
||||
// constructs an HSL color from a RGB Color.
|
||||
explicit _HSL(const COLORREF rgb)
|
||||
{
|
||||
const double r = (double)GetRValue(rgb);
|
||||
const double g = (double)GetGValue(rgb);
|
||||
const double b = (double)GetBValue(rgb);
|
||||
|
||||
const auto [min, max] = std::minmax({ r, g, b });
|
||||
|
||||
const auto diff = max - min;
|
||||
const auto sum = max + min;
|
||||
// Luminance
|
||||
l = max / 255.0;
|
||||
|
||||
// Saturation
|
||||
s = (max == 0) ? 0 : diff / max;
|
||||
|
||||
//Hue
|
||||
double q = (diff == 0) ? 0 : 60.0 / diff;
|
||||
if (max == r)
|
||||
{
|
||||
h = (g < b) ? ((360.0 + q * (g - b)) / 360.0) : ((q * (g - b)) / 360.0);
|
||||
}
|
||||
else if (max == g)
|
||||
{
|
||||
h = (120.0 + q * (b - r)) / 360.0;
|
||||
}
|
||||
else if (max == b)
|
||||
{
|
||||
h = (240.0 + q * (r - g)) / 360.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
h = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//Routine Description:
|
||||
// Finds the "distance" between a given HSL color and an RGB color, using the HSL color space.
|
||||
// This function is designed such that the caller would convert one RGB color to HSL ahead of time,
|
||||
// then compare many RGB colors to that first color.
|
||||
//Arguments:
|
||||
// - phslColorA - a pointer to the first color, as a HSL color.
|
||||
// - rgbColorB - The second color to compare, in RGB color.
|
||||
// Return value:
|
||||
// The "distance" between the two.
|
||||
static double _FindDifference(const _HSL* const phslColorA, const COLORREF rgbColorB)
|
||||
{
|
||||
const _HSL hslColorB = _HSL(rgbColorB);
|
||||
return sqrt(pow((hslColorB.h - phslColorA->h), 2) +
|
||||
pow((hslColorB.s - phslColorA->s), 2) +
|
||||
pow((hslColorB.l - phslColorA->l), 2));
|
||||
}
|
||||
|
||||
//Routine Description:
|
||||
// For a given RGB color Color, finds the nearest color from the array ColorTable, and returns the index of that match.
|
||||
//Arguments:
|
||||
// - Color - The RGB color to fine the nearest color to.
|
||||
// - ColorTable - The array of colors to find a nearest color from.
|
||||
// Return value:
|
||||
// The index in ColorTable of the nearest match to Color.
|
||||
WORD FindNearestTableIndex(const COLORREF Color, const std::basic_string_view<COLORREF> ColorTable)
|
||||
{
|
||||
// Quick check for an exact match in the color table:
|
||||
for (WORD i = 0; i < ColorTable.size(); i++)
|
||||
{
|
||||
if (Color == ColorTable[i])
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// Did not find an exact match - do an expensive comparison to the elements
|
||||
// of the table to find the nearest color.
|
||||
const _HSL hslColor = _HSL(Color);
|
||||
WORD closest = 0;
|
||||
double minDiff = _FindDifference(&hslColor, ColorTable[0]);
|
||||
for (WORD i = 1; i < ColorTable.size(); i++)
|
||||
{
|
||||
double diff = _FindDifference(&hslColor, ColorTable[i]);
|
||||
if (diff < minDiff)
|
||||
{
|
||||
minDiff = diff;
|
||||
closest = i;
|
||||
}
|
||||
}
|
||||
return closest;
|
||||
}
|
||||
|
||||
// Function Description:
|
||||
// - Converts the value of a xterm color table index to the windows color table equivalent.
|
||||
@@ -50,3 +144,26 @@ WORD Xterm256ToWindowsIndex(const size_t xtermTableEntry) noexcept
|
||||
return xtermTableEntry < 16 ? XtermToWindowsIndex(xtermTableEntry) :
|
||||
static_cast<WORD>(xtermTableEntry);
|
||||
}
|
||||
|
||||
//Routine Description:
|
||||
// Returns the exact entry from the color table, if it's in there.
|
||||
//Arguments:
|
||||
// - Color - The RGB color to fine the nearest color to.
|
||||
// - ColorTable - The array of colors to find a nearest color from.
|
||||
// Return value:
|
||||
// The index in ColorTable of the nearest match to Color.
|
||||
bool FindTableIndex(const COLORREF Color,
|
||||
const std::basic_string_view<COLORREF> ColorTable,
|
||||
_Out_ WORD* const pFoundIndex)
|
||||
{
|
||||
*pFoundIndex = 0;
|
||||
for (WORD i = 0; i < ColorTable.size(); i++)
|
||||
{
|
||||
if (ColorTable[i] == Color)
|
||||
{
|
||||
*pFoundIndex = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -356,8 +356,8 @@ Microsoft::Console::CursorBlinker& CONSOLE_INFORMATION::GetCursorBlinker() noexc
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Generates a CHAR_INFO for this output cell, using the TextAttribute
|
||||
// GetLegacyAttributes method to generate the legacy style attributes.
|
||||
// - Generates a CHAR_INFO for this output cell, using our
|
||||
// GenerateLegacyAttributes method to generate the legacy style attributes.
|
||||
// Arguments:
|
||||
// - cell: The cell to get the CHAR_INFO from
|
||||
// Return Value:
|
||||
@@ -371,7 +371,8 @@ CHAR_INFO CONSOLE_INFORMATION::AsCharInfo(const OutputCellView& cell) const noex
|
||||
// use gci to look up the correct legacy attributes to use
|
||||
// (for mapping RGB values to the nearest table value)
|
||||
const auto& attr = cell.TextAttr();
|
||||
ci.Attributes = attr.GetLegacyAttributes();
|
||||
ci.Attributes = GenerateLegacyAttributes(attr);
|
||||
;
|
||||
ci.Attributes |= cell.DbcsAttr().GeneratePublicApiAttributeFormat();
|
||||
return ci;
|
||||
}
|
||||
|
||||
@@ -881,7 +881,7 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
|
||||
(target.Y == -currentBufferDimensions.Y);
|
||||
const bool noClipProvided = clip == std::nullopt;
|
||||
const bool fillIsBlank = (fillCharacter == UNICODE_SPACE) &&
|
||||
(fillAttribute == buffer.GetAttributes().GetLegacyAttributes());
|
||||
(fillAttribute == gci.GenerateLegacyAttributes(buffer.GetAttributes()));
|
||||
|
||||
if (sourceIsWholeBuffer && targetIsNegativeBufferHeight && noClipProvided && fillIsBlank)
|
||||
{
|
||||
|
||||
@@ -41,7 +41,7 @@ using namespace Microsoft::Console::Interactivity;
|
||||
NTSTATUS Status = SCREEN_INFORMATION::CreateInstance(gci.GetWindowSize(),
|
||||
fiFont,
|
||||
gci.GetScreenBufferSize(),
|
||||
TextAttribute{},
|
||||
gci.GetDefaultAttributes(),
|
||||
TextAttribute{ gci.GetPopupFillAttribute() },
|
||||
gci.GetCursorSize(),
|
||||
&gci.ScreenBuffers);
|
||||
@@ -148,7 +148,8 @@ std::vector<WORD> ReadOutputAttributes(const SCREEN_INFORMATION& screenInfo,
|
||||
// While we haven't read enough cells yet and the iterator is still valid (hasn't reached end of buffer)
|
||||
while (amountRead < amountToRead && it)
|
||||
{
|
||||
const auto legacyAttributes = it->TextAttr().GetLegacyAttributes();
|
||||
const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||
const auto legacyAttributes = gci.GenerateLegacyAttributes(it->TextAttr());
|
||||
|
||||
// If the first thing we read is trailing, pad with a space.
|
||||
// OR If the last thing we read is leading, pad with a space.
|
||||
|
||||
@@ -56,7 +56,7 @@ Abstract:
|
||||
#include <intsafe.h>
|
||||
#pragma prefast(pop)
|
||||
#include <strsafe.h>
|
||||
#include <cwchar>
|
||||
#include <wchar.h>
|
||||
#include <mmsystem.h>
|
||||
#include "utils.hpp"
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "handle.h"
|
||||
#include "../buffer/out/CharRow.hpp"
|
||||
|
||||
#include <cmath>
|
||||
#include <math.h>
|
||||
#include "../interactivity/inc/ServiceLocator.hpp"
|
||||
#include "../types/inc/Viewport.hpp"
|
||||
#include "../types/inc/GlyphWidth.hpp"
|
||||
@@ -356,8 +356,8 @@ void SCREEN_INFORMATION::GetScreenBufferInformation(_Out_ PCOORD pcoordSize,
|
||||
|
||||
*psrWindow = _viewport.ToInclusive();
|
||||
|
||||
*pwAttributes = GetAttributes().GetLegacyAttributes();
|
||||
*pwPopupAttributes = _PopupAttributes.GetLegacyAttributes();
|
||||
*pwAttributes = gci.GenerateLegacyAttributes(GetAttributes());
|
||||
*pwPopupAttributes = gci.GenerateLegacyAttributes(_PopupAttributes);
|
||||
|
||||
// the copy length must be constant for now to keep OACR happy with buffer overruns.
|
||||
for (size_t i = 0; i < COLOR_TABLE_SIZE; i++)
|
||||
@@ -572,6 +572,8 @@ void SCREEN_INFORMATION::NotifyAccessibilityEventing(const short sStartX,
|
||||
const short sEndX,
|
||||
const short sEndY)
|
||||
{
|
||||
const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||
|
||||
// Fire off a winevent to let accessibility apps know what changed.
|
||||
if (IsActiveScreenBuffer())
|
||||
{
|
||||
@@ -584,7 +586,7 @@ void SCREEN_INFORMATION::NotifyAccessibilityEventing(const short sStartX,
|
||||
{
|
||||
const auto cellData = GetCellDataAt({ sStartX, sStartY });
|
||||
const LONG charAndAttr = MAKELONG(Utf16ToUcs2(cellData->Chars()),
|
||||
cellData->TextAttr().GetLegacyAttributes());
|
||||
gci.GenerateLegacyAttributes(cellData->TextAttr()));
|
||||
_pAccessibilityNotifier->NotifyConsoleUpdateSimpleEvent(MAKELONG(sStartX, sStartY),
|
||||
charAndAttr);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@ Revision History:
|
||||
|
||||
#include "..\host\RenderData.hpp"
|
||||
|
||||
#include "..\inc\IDefaultColorProvider.hpp"
|
||||
|
||||
// clang-format off
|
||||
// Flags flags
|
||||
#define CONSOLE_IS_ICONIC 0x00000001
|
||||
@@ -73,7 +75,8 @@ class CommandHistory;
|
||||
|
||||
class CONSOLE_INFORMATION :
|
||||
public Settings,
|
||||
public Microsoft::Console::IIoProvider
|
||||
public Microsoft::Console::IIoProvider,
|
||||
public Microsoft::Console::IDefaultColorProvider
|
||||
{
|
||||
public:
|
||||
CONSOLE_INFORMATION();
|
||||
|
||||
@@ -349,10 +349,6 @@ void Settings::Validate()
|
||||
}
|
||||
}
|
||||
|
||||
// At this point the default fill attributes are fully initialized
|
||||
// so we can pass on the final colors to the TextAttribute class.
|
||||
TextAttribute::SetLegacyDefaultAttributes(_wFillAttribute);
|
||||
|
||||
FAIL_FAST_IF(!(_dwWindowSize.X > 0));
|
||||
FAIL_FAST_IF(!(_dwWindowSize.Y > 0));
|
||||
FAIL_FAST_IF(!(_dwScreenBufferSize.X > 0));
|
||||
@@ -761,6 +757,19 @@ COLORREF Settings::GetColorTableEntry(const size_t index) const
|
||||
return _colorTable.at(index);
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - Generates a legacy attribute from the given TextAttributes.
|
||||
// This needs to be a method on the Settings because the generated index
|
||||
// is dependent upon the default fill attributes.
|
||||
// Parameters:
|
||||
// - attributes - The TextAttributes to generate a legacy attribute for.
|
||||
// Return value:
|
||||
// - A WORD representing the legacy attributes that most closely represent the given fullcolor attributes.
|
||||
WORD Settings::GenerateLegacyAttributes(const TextAttribute attributes) const
|
||||
{
|
||||
return attributes.GetLegacyAttributes(_wFillAttribute);
|
||||
}
|
||||
|
||||
COLORREF Settings::GetCursorColor() const noexcept
|
||||
{
|
||||
return _CursorColor;
|
||||
@@ -811,6 +820,20 @@ void Settings::SetDefaultBackgroundColor(const COLORREF defaultBackground) noexc
|
||||
_DefaultBackground = defaultBackground;
|
||||
}
|
||||
|
||||
TextAttribute Settings::GetDefaultAttributes() const noexcept
|
||||
{
|
||||
auto attrs = TextAttribute{ _wFillAttribute };
|
||||
if (_DefaultForeground != INVALID_COLOR)
|
||||
{
|
||||
attrs.SetDefaultForeground();
|
||||
}
|
||||
if (_DefaultBackground != INVALID_COLOR)
|
||||
{
|
||||
attrs.SetDefaultBackground();
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
bool Settings::IsTerminalScrolling() const noexcept
|
||||
{
|
||||
return _TerminalScrolling;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user