Skip to content

Commit 5f9add4

Browse files
committed
Merge branch 'dev/migrie/fhl/non-terminal-panes-2023' into dev/migrie/fhl/scratchpad-pane
2 parents 2d40306 + 11126f9 commit 5f9add4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+1849
-535
lines changed

.github/actions/spelling/allow/names.txt

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ mikegr
5454
mikemaccana
5555
miloush
5656
miniksa
57+
nguyen
5758
niksa
5859
nvaccess
5960
nvda

.github/actions/spelling/expect/expect.txt

+1
Original file line numberDiff line numberDiff line change
@@ -2132,6 +2132,7 @@ WDDMCONSOLECONTEXT
21322132
wdm
21332133
webpage
21342134
websites
2135+
websockets
21352136
wekyb
21362137
wex
21372138
wextest

README.md

+5-3
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ package:
7070
winget install --id Microsoft.WindowsTerminal -e
7171
```
7272

73+
> **Note** Due to a dependency issue, Terminal's current versions cannot be installed via the Windows Package Manager CLI. To install the stable release 1.17 or later, or the Preview release 1.18 or later, please use an alternative installation method.
74+
7375
#### Via Chocolatey (unofficial)
7476

7577
[Chocolatey](https://chocolatey.org) users can download and install the latest
@@ -271,10 +273,10 @@ similar open/closed preexisting issues before creating a new issue.**
271273
If you would like to ask a question that you feel doesn't warrant an issue
272274
(yet), please reach out to us via Twitter:
273275

274-
* Kayla Cinnamon, Program Manager:
275-
[@cinnamon\_msft](https://twitter.com/cinnamon_msft)
276+
* Christopher Nguyen, Product Manager:
277+
[@nguyen_dows](https://twitter.com/nguyen_dows)
276278
* Dustin Howett, Engineering Lead: [@dhowett](https://twitter.com/DHowett)
277-
* Mike Griese, Senior Developer: [@zadjii](https://twitter.com/zadjii)
279+
* Mike Griese, Senior Developer: [@zadjii@mastodon.social](https://mastodon.social/@zadjii)
278280
* Carlos Zamora, Developer: [@cazamor_msft](https://twitter.com/cazamor_msft)
279281
* Pankaj Bhojwani, Developer
280282
* Leonard Hecker, Developer: [@LeonardHecker](https://twitter.com/LeonardHecker)

src/buffer/out/textBuffer.cpp

+114
Original file line numberDiff line numberDiff line change
@@ -2660,6 +2660,9 @@ try
26602660
// Set size back to real size as it will be taking over the rendering duties.
26612661
newCursor.SetSize(ulSize);
26622662

2663+
newBuffer._marks = oldBuffer._marks;
2664+
newBuffer._trimMarksOutsideBuffer();
2665+
26632666
return S_OK;
26642667
}
26652668
CATCH_RETURN()
@@ -2869,3 +2872,114 @@ PointTree TextBuffer::GetPatterns(const til::CoordType firstRow, const til::Coor
28692872
PointTree result(std::move(intervals));
28702873
return result;
28712874
}
2875+
2876+
const std::vector<ScrollMark>& TextBuffer::GetMarks() const noexcept
2877+
{
2878+
return _marks;
2879+
}
2880+
2881+
// Remove all marks between `start` & `end`, inclusive.
2882+
void TextBuffer::ClearMarksInRange(
2883+
const til::point start,
2884+
const til::point end)
2885+
{
2886+
auto inRange = [&start, &end](const ScrollMark& m) {
2887+
return (m.start >= start && m.start <= end) ||
2888+
(m.end >= start && m.end <= end);
2889+
};
2890+
2891+
_marks.erase(std::remove_if(_marks.begin(),
2892+
_marks.end(),
2893+
inRange),
2894+
_marks.end());
2895+
}
2896+
void TextBuffer::ClearAllMarks() noexcept
2897+
{
2898+
_marks.clear();
2899+
}
2900+
2901+
// Adjust all the marks in the y-direction by `delta`. Positive values move the
2902+
// marks down (the positive y direction). Negative values move up. This will
2903+
// trim marks that are no longer have a start in the bounds of the buffer
2904+
void TextBuffer::ScrollMarks(const int delta)
2905+
{
2906+
for (auto& mark : _marks)
2907+
{
2908+
mark.start.y += delta;
2909+
2910+
// If the mark had sub-regions, then move those pointers too
2911+
if (mark.commandEnd.has_value())
2912+
{
2913+
(*mark.commandEnd).y += delta;
2914+
}
2915+
if (mark.outputEnd.has_value())
2916+
{
2917+
(*mark.outputEnd).y += delta;
2918+
}
2919+
}
2920+
_trimMarksOutsideBuffer();
2921+
}
2922+
2923+
// Method Description:
2924+
// - Add a mark to our list of marks, and treat it as the active "prompt". For
2925+
// the sake of shell integration, we need to know which mark represents the
2926+
// current prompt/command/output. Internally, we'll always treat the _last_
2927+
// mark in the list as the current prompt.
2928+
// Arguments:
2929+
// - m: the mark to add.
2930+
void TextBuffer::StartPromptMark(const ScrollMark& m)
2931+
{
2932+
_marks.push_back(m);
2933+
}
2934+
// Method Description:
2935+
// - Add a mark to our list of marks. Don't treat this as the active prompt.
2936+
// This should be used for marks created by the UI or from other user input.
2937+
// By inserting at the start of the list, we can separate out marks that were
2938+
// generated by client programs vs ones created by the user.
2939+
// Arguments:
2940+
// - m: the mark to add.
2941+
void TextBuffer::AddMark(const ScrollMark& m)
2942+
{
2943+
_marks.insert(_marks.begin(), m);
2944+
}
2945+
2946+
void TextBuffer::_trimMarksOutsideBuffer()
2947+
{
2948+
const auto height = GetSize().Height();
2949+
_marks.erase(std::remove_if(_marks.begin(),
2950+
_marks.end(),
2951+
[height](const auto& m) {
2952+
return (m.start.y < 0) ||
2953+
(m.start.y >= height);
2954+
}),
2955+
_marks.end());
2956+
}
2957+
2958+
void TextBuffer::SetCurrentPromptEnd(const til::point pos) noexcept
2959+
{
2960+
if (_marks.empty())
2961+
{
2962+
return;
2963+
}
2964+
auto& curr{ _marks.back() };
2965+
curr.end = pos;
2966+
}
2967+
void TextBuffer::SetCurrentCommandEnd(const til::point pos) noexcept
2968+
{
2969+
if (_marks.empty())
2970+
{
2971+
return;
2972+
}
2973+
auto& curr{ _marks.back() };
2974+
curr.commandEnd = pos;
2975+
}
2976+
void TextBuffer::SetCurrentOutputEnd(const til::point pos, ::MarkCategory category) noexcept
2977+
{
2978+
if (_marks.empty())
2979+
{
2980+
return;
2981+
}
2982+
auto& curr{ _marks.back() };
2983+
curr.outputEnd = pos;
2984+
curr.category = category;
2985+
}

src/buffer/out/textBuffer.hpp

+48
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,41 @@ namespace Microsoft::Console::Render
6464
class Renderer;
6565
}
6666

67+
enum class MarkCategory
68+
{
69+
Prompt = 0,
70+
Error = 1,
71+
Warning = 2,
72+
Success = 3,
73+
Info = 4
74+
};
75+
struct ScrollMark
76+
{
77+
std::optional<til::color> color;
78+
til::point start;
79+
til::point end; // exclusive
80+
std::optional<til::point> commandEnd;
81+
std::optional<til::point> outputEnd;
82+
83+
MarkCategory category{ MarkCategory::Info };
84+
// Other things we may want to think about in the future are listed in
85+
// GH#11000
86+
87+
bool HasCommand() const noexcept
88+
{
89+
return commandEnd.has_value() && *commandEnd != end;
90+
}
91+
bool HasOutput() const noexcept
92+
{
93+
return outputEnd.has_value() && *outputEnd != *commandEnd;
94+
}
95+
std::pair<til::point, til::point> GetExtent() const
96+
{
97+
til::point realEnd{ til::coalesce_value(outputEnd, commandEnd, end) };
98+
return std::make_pair(til::point{ start }, realEnd);
99+
}
100+
};
101+
67102
class TextBuffer final
68103
{
69104
public:
@@ -228,6 +263,16 @@ class TextBuffer final
228263
void CopyPatterns(const TextBuffer& OtherBuffer);
229264
interval_tree::IntervalTree<til::point, size_t> GetPatterns(const til::CoordType firstRow, const til::CoordType lastRow) const;
230265

266+
const std::vector<ScrollMark>& GetMarks() const noexcept;
267+
void ClearMarksInRange(const til::point start, const til::point end);
268+
void ClearAllMarks() noexcept;
269+
void ScrollMarks(const int delta);
270+
void StartPromptMark(const ScrollMark& m);
271+
void AddMark(const ScrollMark& m);
272+
void SetCurrentPromptEnd(const til::point pos) noexcept;
273+
void SetCurrentCommandEnd(const til::point pos) noexcept;
274+
void SetCurrentOutputEnd(const til::point pos, ::MarkCategory category) noexcept;
275+
231276
private:
232277
void _reserve(til::size screenBufferSize, const TextAttribute& defaultAttributes);
233278
void _commit(const std::byte* row);
@@ -251,6 +296,7 @@ class TextBuffer final
251296
til::point _GetWordEndForAccessibility(const til::point target, const std::wstring_view wordDelimiters, const til::point limit) const;
252297
til::point _GetWordEndForSelection(const til::point target, const std::wstring_view wordDelimiters) const;
253298
void _PruneHyperlinks();
299+
void _trimMarksOutsideBuffer();
254300

255301
static void _AppendRTFText(std::ostringstream& contentBuilder, const std::wstring_view& text);
256302

@@ -327,6 +373,8 @@ class TextBuffer final
327373

328374
bool _isActiveBuffer = false;
329375

376+
std::vector<ScrollMark> _marks;
377+
330378
#ifdef UNIT_TESTING
331379
friend class TextBufferTests;
332380
friend class UiaTextRangeTests;

src/cascadia/TerminalApp/App.xaml

+9
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,9 @@
174174

175175
<SolidColorBrush x:Key="SettingsUiTabBrush"
176176
Color="#0c0c0c" />
177+
178+
<SolidColorBrush x:Key="BroadcastPaneBorderColor"
179+
Color="{StaticResource SystemAccentColorDark2}" />
177180
</ResourceDictionary>
178181

179182
<ResourceDictionary x:Key="Light">
@@ -190,6 +193,9 @@
190193

191194
<SolidColorBrush x:Key="SettingsUiTabBrush"
192195
Color="#ffffff" />
196+
197+
<SolidColorBrush x:Key="BroadcastPaneBorderColor"
198+
Color="{StaticResource SystemAccentColorLight2}" />
193199
</ResourceDictionary>
194200

195201
<ResourceDictionary x:Key="HighContrast">
@@ -210,6 +216,9 @@
210216

211217
<StaticResource x:Key="SettingsUiTabBrush"
212218
ResourceKey="SystemControlBackgroundBaseLowBrush" />
219+
220+
<SolidColorBrush x:Key="BroadcastPaneBorderColor"
221+
Color="{StaticResource SystemColorHighlightColor}" />
213222
</ResourceDictionary>
214223

215224
</ResourceDictionary.ThemeDictionaries>

src/cascadia/TerminalApp/AppActionHandlers.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -1273,6 +1273,17 @@ namespace winrt::TerminalApp::implementation
12731273
}
12741274
}
12751275

1276+
void TerminalPage::_HandleToggleBroadcastInput(const IInspectable& /*sender*/,
1277+
const ActionEventArgs& args)
1278+
{
1279+
if (const auto activeTab{ _GetFocusedTabImpl() })
1280+
{
1281+
activeTab->ToggleBroadcastInput();
1282+
args.Handled(true);
1283+
}
1284+
// If the focused tab wasn't a TerminalTab, then leave handled=false
1285+
}
1286+
12761287
void TerminalPage::_HandleRestartConnection(const IInspectable& /*sender*/,
12771288
const ActionEventArgs& args)
12781289
{

src/cascadia/TerminalApp/CommandPalette.xaml

+8
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
HorizontalAlignment="Right"
7676
VerticalAlignment="Center"
7777
AutomationProperties.AccessibilityView="Raw"
78+
Background="{ThemeResource FlyoutPresenterBackground}"
7879
Style="{ThemeResource KeyChordBorderStyle}"
7980
Visibility="{x:Bind Item.KeyChordText, Mode=OneWay, Converter={StaticResource CommandKeyChordVisibilityConverter}}">
8081

@@ -204,6 +205,13 @@
204205
Glyph="&#xE72E;"
205206
Visibility="{x:Bind Item.(local:TabPaletteItem.TabStatus).IsReadOnlyActive, Mode=OneWay}" />
206207

208+
<FontIcon x:Name="HeaderBroadcastIcon"
209+
Margin="0,0,8,0"
210+
FontFamily="Segoe MDL2 Assets"
211+
FontSize="12"
212+
Glyph="&#xEC05;"
213+
Visibility="{x:Bind Item.(local:TabPaletteItem.TabStatus).IsInputBroadcastActive, Mode=OneWay}" />
214+
207215
</StackPanel>
208216
</Grid>
209217
</DataTemplate>

0 commit comments

Comments
 (0)