Compare commits

..

81 Commits

Author SHA1 Message Date
Dustin L. Howett
6e1ce8de26 Migrate spelling-0.0.21 changes from main 2020-06-26 14:39:45 -05:00
Dustin L. Howett
5e13c37217 Migrate spelling-0.0.19 changes from main 2020-06-26 14:39:45 -05:00
Mike Griese
6328b1adda Merge branch 'dev/migrie/f/2046-Command-Palette-with-autogen-action-names' into dev/migrie/f/execute-commandlines
# Conflicts:
#	src/cascadia/TerminalApp/ActionAndArgs.cpp
#	src/cascadia/TerminalApp/ActionArgs.cpp
#	src/cascadia/TerminalApp/ActionArgs.h
#	src/cascadia/TerminalApp/ActionArgs.idl
#	src/cascadia/TerminalApp/CommandPalette.cpp
#	src/cascadia/TerminalApp/ShortcutActionDispatch.cpp
#	src/cascadia/TerminalApp/ShortcutActionDispatch.h
#	src/cascadia/TerminalApp/ShortcutActionDispatch.idl
#	src/cascadia/TerminalApp/TerminalPage.cpp
#	src/cascadia/TerminalControl/TermControl.idl
2020-06-26 14:39:45 -05:00
Mike Griese
177cf1caae use a border instead of a grid 2020-06-26 08:37:22 -05:00
Mike Griese
75473c50fb Use the visibility changed event, not the ToggleVisibility function.
Also misc spellchecks, nits.
2020-06-26 07:51:48 -05:00
Mike Griese
76cb9654e1 hey, why not use keybindings directly from the command palette? 2020-06-25 12:33:05 -05:00
Mike Griese
e967801cdf actually, just do all of #6645 2020-06-25 11:54:51 -05:00
Mike Griese
50cfd84dd2 add a little message when no matches are found 2020-06-25 11:34:02 -05:00
Mike Griese
33860f7c1a good bot 2020-06-25 11:17:28 -05:00
Mike Griese
860a3c7b23 add support for clicking on individual items in the command palette 2020-06-25 11:16:29 -05:00
Mike Griese
eae88a9fdb light dismiss on click, better sizing 2020-06-25 10:33:48 -05:00
Mike Griese
137aea367a unordered_maps, mad genius sorting, and a good idea about ESC 2020-06-25 09:37:46 -05:00
Mike Griese
8a93b1dd5d Merge remote-tracking branch 'origin/master' into dev/migrie/f/2046-Command-Palette-with-autogen-action-names
# Conflicts:
#	src/cascadia/TerminalApp/ActionAndArgs.cpp
#	src/cascadia/TerminalApp/ActionArgs.cpp
#	src/cascadia/TerminalApp/AppActionHandlers.cpp
#	src/cascadia/TerminalApp/ShortcutActionDispatch.cpp
#	src/cascadia/TerminalApp/ShortcutActionDispatch.h
#	src/cascadia/TerminalApp/ShortcutActionDispatch.idl
#	src/cascadia/TerminalApp/TerminalPage.cpp
#	src/cascadia/TerminalApp/TerminalPage.h
2020-06-25 09:13:51 -05:00
Mike Griese
6ca7d0e054 use iterators, because this isn't 1999 2020-06-24 16:59:35 -05:00
Mike Griese
6f1dc5c9fa Make command fuzzy-searching heaps better
Weight consecutive matched chars heigher.
  Sort results with the same weight.
  Co-authored by: @greg904
2020-06-24 16:40:22 -05:00
Mike Griese
b5be04c3ae only the simplest remaining feedback 2020-06-24 14:33:24 -05:00
Mike Griese
48d4e248b7 misc fixes from PR 2020-06-23 16:54:42 -05:00
Mike Griese
264618ae88 a ton of code cleanup from review 2020-06-23 13:01:27 -05:00
Mike Griese
f892e52077 align visuals with the SearchBoxControl 2020-06-23 11:50:40 -05:00
Mike Griese
b90cc38f0f Merge remote-tracking branch 'origin/master' into dev/migrie/f/2046-Command-Palette-with-autogen-action-names 2020-06-22 11:03:32 -05:00
Mike Griese
92b3453119 clean up these tests 2020-06-22 11:03:14 -05:00
Mike Griese
e25da60775 fix the last case of CommandTests::LayerCommand 2020-06-22 10:49:12 -05:00
Mike Griese
cee5fc9226 This is a ton of new tests 2020-06-22 10:31:12 -05:00
Mike Griese
10e91a823d strings for every possible action, and args value 2020-06-19 16:55:41 -05:00
Mike Griese
d1a72613c7 Use resources for the majority of command names 2020-06-19 15:46:13 -05:00
Mike Griese
3e5eb73597 proof of concept - have the names auto-generated from actions 2020-06-19 14:17:23 -05:00
Mike Griese
cc2fd9b490 fix this build 2020-06-19 11:22:14 -05:00
Mike Griese
45243bbee6 Merge remote-tracking branch 'origin/master' into dev/migrie/f/2046-Command-Palette-v2
# Conflicts:
#	src/cascadia/TerminalApp/ActionAndArgs.cpp
2020-06-19 11:09:25 -05:00
Mike Griese
52eb2e5faa Merge commit '827cc42' into dev/migrie/f/2046-Command-Palette-v2
# Conflicts:
#	doc/specs/#2046 - Command Palette.md
2020-06-19 11:07:48 -05:00
Mike Griese
8b094fdfde Merge commit 'db518c0' into dev/migrie/f/2046-Command-Palette-v2 2020-06-19 10:59:07 -05:00
Mike Griese
7a94b8f725 stash these tests in progress 2020-06-11 16:29:06 -05:00
Mike Griese
e2f5f75471 start adding tests 2020-06-11 12:40:57 -05:00
Mike Griese
7ac7fd1de9 Merge remote-tracking branch 'origin/master' into dev/migrie/f/2046-Command-Palette-v2 2020-06-11 12:15:27 -05:00
Mike Griese
dd684cbca1 implement a weighted ordering for command palette entries 2020-06-10 09:59:55 -05:00
Mike Griese
edc8b557e1 Add much better key chord text to the command palette 2020-06-10 08:53:34 -05:00
Mike Griese
82f968d8d5 If a key is bound to that action, then display the keybinding in the palette 2020-06-09 16:58:51 -05:00
Mike Griese
67c7969879 I couldn't tell you how long this took 2020-06-09 16:30:55 -05:00
Mike Griese
b3d8f0e279 Merge remote-tracking branch 'origin/master' into dev/migrie/f/2046-Command-Palette-v2 2020-06-09 12:33:36 -05:00
Mike Griese
10ace041c3 Trim leading whitespace form the commandline 2020-06-05 15:37:31 -05:00
Mike Griese
4d23121a7e A bunch of cleanup for review 2020-06-05 15:30:32 -05:00
Mike Griese
414007fdd8 This works but it's dirty 2020-06-05 15:05:14 -05:00
Mike Griese
72c0601d00 split-pane ; split-pane at runtime doesn't work, pt2
This does work to split multiple panes at runtime. It definitely crashes
  when the panes get too small, we might be able to adapt Pane::CanSplit to
  be smart about when it's children don't quite have a size yet.
2020-06-05 09:30:57 -05:00
Mike Griese
b3225db167 split-pane ; split-pane at runtime doesn't work, pt1
I thought maybe breaking up the dispatcher calls would just magic fix this for me. It doesn't.
2020-06-05 09:29:04 -05:00
Mike Griese
2517183b63 Add incredible support for commandline mode
easy_button.jpg
2020-06-05 09:27:57 -05:00
Mike Griese
9fbcbcc9d8 Cleanup for review 2020-06-05 08:39:03 -05:00
Mike Griese
73aefc18e8 do it with multiple args 2020-06-05 08:01:39 -05:00
Mike Griese
a02585da35 Whoop, this works for parsing a single command! This code's horribly dirty, but _it works_ 2020-06-04 17:00:24 -05:00
Mike Griese
2cf69338cd Add an ExecuteCommandline ShortcutAction, don't implement quite yet 2020-06-04 14:54:03 -05:00
Mike Griese
d71d8d7b32 Ready for review. 2020-06-04 12:29:22 -05:00
Mike Griese
9d411d405c Make the commands a map, so we can override on "name" 2020-06-04 11:48:38 -05:00
Mike Griese
58be8cd117 Tons of commenting 2020-06-04 11:21:46 -05:00
Mike Griese
487f33ee89 Merge commit '6e6979abe' into dev/migrie/f/2046-Command-Palette-v2
# Conflicts:
#	src/cascadia/TerminalApp/ActionAndArgs.cpp
#	src/cascadia/TerminalApp/AppKeyBindingsSerialization.cpp
2020-06-04 10:15:40 -05:00
Mike Griese
829beda501 Merge remote-tracking branch 'origin/master' into dev/migrie/f/2046-Command-Palette-v2
# Conflicts:
#	src/cascadia/TerminalApp/GlobalAppSettings.cpp
#	src/cascadia/TerminalApp/GlobalAppSettings.h
2020-06-04 10:02:40 -05:00
Mike Griese
6e6979abe8 Extract ActionAndArgs::FromJson into it's own class, so it can be re-used later 2020-06-04 09:28:21 -05:00
Mike Griese
1fbe8e415d Turns out, the shadow on the menuflyout isn't my fault, it's on everything that uses MUX 2020-05-29 12:45:39 -05:00
Mike Griese
fa93fdc034 Well, this is neat, and works, but requires 18362 and also casts a shadow on the menuflyout??? 2020-05-29 12:19:04 -05:00
Mike Griese
cf6e1f273a Try to do this with a shadow, but it crashes inexplicably 2020-05-29 11:44:38 -05:00
Mike Griese
99059451d8 Return focus to the active control when closed 2020-05-29 11:29:01 -05:00
Mike Griese
a309191461 Rename private methods, fix wraparound logic 2020-05-29 11:14:56 -05:00
Mike Griese
e1be26b184 Do this in WinRTUtils instead of hackily doing it manually 2020-05-29 09:48:30 -05:00
Mike Griese
bc546dbdb0 Add some stability
Don't die when we encounter an unexpected key
  Reload successfully
2020-05-29 09:42:47 -05:00
Mike Griese
00763fda9e Add duplicate pane to the default commands 2020-05-29 07:47:29 -05:00
Mike Griese
b88be4534b Make sure to scroll the selected item into view 2020-05-29 07:43:12 -05:00
Mike Griese
207666e34d Add a ton of default commands 2020-05-29 07:32:43 -05:00
Mike Griese
62b9a0d1c0 Move the action into it's own sub-object 2020-05-28 16:44:38 -05:00
Mike Griese
02f47f49c3 Make the action names map public, so the ToJson in AKBSerialization can use it 2020-05-28 16:40:04 -05:00
Mike Griese
6905065fcf Merge remote-tracking branch 'origin/master' into dev/migrie/f/2046-Command-Palette-v2
# Conflicts:
#	src/cascadia/TerminalApp/TerminalPage.h
2020-05-28 15:29:23 -05:00
Mike Griese
0416a944a2 Hook up the parsing of ActionAndArgss to the command palette 2020-05-28 15:09:45 -05:00
Mike Griese
3627d8abd5 This should have been in the previous commit 2020-05-28 15:08:57 -05:00
Mike Griese
33a9e32736 Get names from the resources if provided as an object, not a string 2020-05-28 12:56:17 -05:00
Mike Griese
75af4cabbb Hook up all the parsing once again 2020-05-28 12:31:49 -05:00
Mike Griese
43bd483962 Blind port these files from the old branch 2020-05-28 11:26:25 -05:00
Mike Griese
0672812e6f good bot 2020-05-28 10:29:09 -05:00
Mike Griese
f53553f4e4 Merge remote-tracking branch 'origin/master' into dev/migrie/s/5400-CommandPalette-v1 2020-05-28 10:27:58 -05:00
Mike Griese
11130a4895 Add some notes about the advanced tab switcher and how that might interplay with this 2020-05-20 09:15:27 -05:00
Mike Griese
0886e8f12d Merge remote-tracking branch 'origin/master' into dev/migrie/s/5400-CommandPalette-v1 2020-05-20 08:47:50 -05:00
Mike Griese
2e564368c8 Move this section to 'future considerations' 2020-05-07 12:17:00 -05:00
Mike Griese
ead76d7f16 Merge remote-tracking branch 'origin/master' into dev/migrie/s/5400-CommandPalette-v1 2020-05-07 12:11:48 -05:00
Mike Griese
614d1b21d6 last little todos for review 2020-04-30 15:20:25 -05:00
Mike Griese
fe640ff894 move this spec out of drafts/ 2020-04-30 15:03:52 -05:00
Mike Griese
c56eb8fd93 Add a ton of text regarding Commandline Mode vs Action Mode 2020-04-30 15:02:59 -05:00
190 changed files with 2757 additions and 4294 deletions

View File

@@ -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:

View File

@@ -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. |

View File

@@ -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"

View File

@@ -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)

Binary file not shown.

Binary file not shown.

View File

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

View File

@@ -7,7 +7,7 @@
#include "targetver.h"
#include <cstdio>
#include <stdio.h>
#include <tchar.h>
// TODO: reference additional headers your program requires here

View File

@@ -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;
}

View File

@@ -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,

View File

@@ -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 };
}

View File

@@ -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:

View File

@@ -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())

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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
{

View File

@@ -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();

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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" />

View File

@@ -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());

View File

@@ -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>&quot;$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\runtimes\win10-$(Native-Platform)\native\&quot;</_MUXBinRoot>
<_MUXBinRoot>&quot;$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.4.2-prerelease.200604001\runtimes\win10-$(Native-Platform)\native\&quot;</_MUXBinRoot>
</PropertyGroup>
<!-- We actually can just straight up reference MUX here, it's fine -->
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.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>

View File

@@ -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" />

View File

@@ -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") },

View File

@@ -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"

View File

@@ -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" };

View File

@@ -101,6 +101,11 @@ namespace TerminalApp
SplitType SplitMode { get; };
};
[default_interface] runtimeclass ExecuteCommandlineArgs : IActionArgs
{
String Commandline;
}
[default_interface] runtimeclass OpenSettingsArgs : IActionArgs
{
SettingsTarget Target { get; };

View File

@@ -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()

View File

@@ -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);
}
}
}
}

View File

@@ -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;
}

View File

@@ -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);

View File

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

View File

@@ -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();

View File

@@ -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;

View File

@@ -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;
}
}

View File

@@ -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();

View File

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

View File

@@ -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();
}
}

View File

@@ -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);
}

View File

@@ -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();
};
}

View File

@@ -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();
}
}
}

View File

@@ -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();
};
}

View File

@@ -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"

View File

@@ -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));

View File

@@ -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);

View File

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

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -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;

View File

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

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;

View File

@@ -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<>);

View File

@@ -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);

View File

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

View File

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

View File

@@ -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);
}

View File

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

View File

@@ -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;
}

View File

@@ -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"

View File

@@ -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.

View File

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

View File

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

View File

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

View File

@@ -10,7 +10,7 @@
#include "AzureConnection.h"
#include "AzureClientID.h"
#include <sstream>
#include <cstdlib>
#include <stdlib.h>
#include <LibraryResources.h>
#include <unicode.hpp>

View File

@@ -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;

View File

@@ -66,9 +66,6 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
std::array<char, 4096> _buffer;
DWORD _OutputThread();
public:
void _DoOutputThreadWork(std::wstring_view str);
};
}

View File

@@ -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"

View File

@@ -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;

View File

@@ -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();

View File

@@ -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();
}
}

View File

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

View File

@@ -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();
}
});

View File

@@ -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;
};

View File

@@ -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);

View File

@@ -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;

View File

@@ -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()

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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.

View File

@@ -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'))" />

View File

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

View File

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

View File

@@ -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'))" />

View File

@@ -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>&quot;$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\runtimes\win10-$(Native-Platform)\native\&quot;</_MUXBinRoot>
<_MUXBinRoot>&quot;$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.4.2-prerelease.200604001\runtimes\win10-$(Native-Platform)\native\&quot;</_MUXBinRoot>
</PropertyGroup>
<ItemDefinitionGroup>

View File

@@ -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:

View File

@@ -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.

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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)
{

View File

@@ -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.

View File

@@ -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"

View File

@@ -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);
}

View File

@@ -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();

View File

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