Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experimental: add support for scrollbar marks #12948

Merged
merged 33 commits into from
Jun 9, 2022
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
88ff59f
better align overlay, transparent to clicks now
zadjii-msft Mar 22, 2022
18ddace
the start of a bunch of actions
zadjii-msft Mar 22, 2022
be83255
Plumb more actions through
zadjii-msft Mar 23, 2022
66a5d9e
Auto prompt detection on enter
zadjii-msft Mar 23, 2022
928002b
setting to enable scrollbar marks
zadjii-msft Mar 24, 2022
036ebb1
Be able to mark a selection via the action, because that's handy!
zadjii-msft Mar 24, 2022
958dfa3
howd i miuss this
zadjii-msft Apr 19, 2022
fb0bc53
plumb iterm2 marks thru to the control, draw on scrollbar
zadjii-msft Mar 22, 2022
b7a8445
let the user overscroll marks to the start/end
zadjii-msft Apr 20, 2022
df00505
clearing a selection of marks is important too
zadjii-msft Apr 20, 2022
0fa5765
some cleanup
zadjii-msft Apr 20, 2022
a9a8ef9
allow for optional colors
zadjii-msft Apr 20, 2022
3aad0f5
flush that too
zadjii-msft Apr 20, 2022
1a27350
Merge remote-tracking branch 'origin/main' into dev/migrie/f/1527-exp…
zadjii-msft Apr 20, 2022
9e2eb1a
Allow the settings to set marks with an optional color
zadjii-msft Apr 20, 2022
6df37bf
format ; spell
zadjii-msft Apr 20, 2022
00d9408
Merge commit 'eb5c26c' into dev/migrie/f/1527-experimental-marks
zadjii-msft May 5, 2022
f6c8cd7
Merge remote-tracking branch 'origin/main' into dev/migrie/f/1527-exp…
zadjii-msft May 5, 2022
2f08c35
Merge remote-tracking branch 'origin/main' into dev/migrie/f/1527-exp…
zadjii-msft May 24, 2022
39a08ed
classic
zadjii-msft May 24, 2022
d00aadd
some rather simple misses, that I guess are only in Release & audit
zadjii-msft May 24, 2022
1090b88
Cat walking over the keyboard
zadjii-msft May 24, 2022
b441891
make audit happy, I think
zadjii-msft May 26, 2022
02132b8
this makes audit happy, but the interactivity tests are... flaky... i…
zadjii-msft May 26, 2022
a2a3771
this makes a lot more sense now doesn't it
zadjii-msft May 27, 2022
0ece836
this too
zadjii-msft May 27, 2022
b989d00
this fixes the tests, but I don't think I need the test delta
zadjii-msft May 27, 2022
be6616f
That's right, I didn't
zadjii-msft May 27, 2022
be59a71
put behind velocity, fix alt buffer
zadjii-msft Jun 7, 2022
8cb9ae2
loc comments too
zadjii-msft Jun 7, 2022
994e5d4
Merge remote-tracking branch 'origin/main' into dev/migrie/f/1527-exp…
zadjii-msft Jun 7, 2022
25dea23
Merge remote-tracking branch 'origin/main' into dev/migrie/f/1527-exp…
zadjii-msft Jun 9, 2022
7bfdc9d
its happening
zadjii-msft Jun 9, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions src/cascadia/TerminalApp/AppActionHandlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,55 @@ namespace winrt::TerminalApp::implementation
args.Handled(true);
}

void TerminalPage::_HandleScrollToMark(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
if (const auto& realArgs = args.ActionArgs().try_as<ScrollToMarkArgs>())
{
_ApplyToActiveControls([&realArgs](auto& control) {
control.ScrollToMark(realArgs.Direction());
});
}
args.Handled(true);
}
void TerminalPage::_HandleAddMark(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
if (const auto& realArgs = args.ActionArgs().try_as<AddMarkArgs>())
{
_ApplyToActiveControls([realArgs](auto& control) {
Control::ScrollMark mark;
if (realArgs.Color())
{
mark.Color.Color = realArgs.Color().Value();
mark.Color.HasValue = true;
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved
}
else
{
mark.Color.HasValue = false;
}
control.AddMark(mark);
});
}
args.Handled(true);
}
void TerminalPage::_HandleClearMark(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
_ApplyToActiveControls([](auto& control) {
control.ClearMark();
});
args.Handled(true);
}
void TerminalPage::_HandleClearAllMarks(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
_ApplyToActiveControls([](auto& control) {
control.ClearAllMarks();
});
args.Handled(true);
}

void TerminalPage::_HandleFindMatch(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
Expand Down
162 changes: 162 additions & 0 deletions src/cascadia/TerminalControl/ControlCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,28 @@ constexpr const auto UpdatePatternLocationsInterval = std::chrono::milliseconds(

namespace winrt::Microsoft::Terminal::Control::implementation
{
static winrt::Microsoft::Terminal::Core::OptionalColor OptionalFromColor(const til::color& c)
{
Core::OptionalColor result;
result.Color = c;
result.HasValue = true;
return result;
}
static winrt::Microsoft::Terminal::Core::OptionalColor OptionalFromColor(const std::optional<til::color>& c)
{
Core::OptionalColor result;
if (c.has_value())
{
result.Color = *c;
result.HasValue = true;
}
else
{
result.HasValue = false;
}
return result;
}

// Helper static function to ensure that all ambiguous-width glyphs are reported as narrow.
// See microsoft/terminal#2066 for more info.
static bool _IsGlyphWideForceNarrowFallback(const std::wstring_view /* glyph */)
Expand Down Expand Up @@ -1179,6 +1201,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
const int viewHeight,
const int bufferSize)
{
if (!_initializedTerminal)
{
return;
}
// Clear the regex pattern tree so the renderer does not try to render them while scrolling
// We're **NOT** taking the lock here unlike _scrollbarChangeHandler because
// we are already under lock (since this usually happens as a result of writing).
Expand Down Expand Up @@ -1769,4 +1795,140 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// transparency, or our acrylic, or our image.
return Opacity() < 1.0f || UseAcrylic() || !_settings->BackgroundImage().empty() || _settings->UseBackgroundImageForWindow();
}

Windows::Foundation::Collections::IVector<Control::ScrollMark> ControlCore::ScrollMarks() const
{
auto internalMarks{ _terminal->GetScrollMarks() };
auto v = winrt::single_threaded_observable_vector<Control::ScrollMark>();
for (const auto& mark : internalMarks)
{
Control::ScrollMark m{};

// sneaky: always evaluate the color of the mark to a real value
// before shoving it into the optional. If the mark doesn't have a
// specific color set, we'll use the value from the color table
// that's appropriate for this category of mark. If we do have a
// color set, then great we'll use that. The TermControl can then
// always use the value in the Mark regardless if it was actually
// set or not.
m.Color = OptionalFromColor(_terminal->GetColorForMark(mark));
m.Start = mark.start.to_core_point();
m.End = mark.end.to_core_point();

v.Append(m);
}

return v;
}

void ControlCore::AddMark(const Control::ScrollMark& mark)
{
::Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark m{};

if (mark.Color.HasValue)
{
m.color = til::color{ mark.Color.Color };
}

if (HasSelection())
{
m.start = til::point{ _terminal->GetSelectionAnchor() };
m.end = til::point{ _terminal->GetSelectionEnd() };
}
else
{
m.start = m.end = til::point{ _terminal->GetTextBuffer().GetCursor().GetPosition() };
}

// The version of this that only accepts a ScrollMark will automatically
// set the start & end to the cursor position.
_terminal->AddMark(m, m.start, m.end);
}
void ControlCore::ClearMark() { _terminal->ClearMark(); }
void ControlCore::ClearAllMarks() { _terminal->ClearAllMarks(); }

void ControlCore::ScrollToMark(const Control::ScrollToMarkDirection& direction)
{
const auto currentOffset = ScrollOffset();
const auto& marks{ _terminal->GetScrollMarks() };

std::optional<DispatchTypes::ScrollMark> tgt;

switch (direction)
{
case ScrollToMarkDirection::Last:
{
int highest = currentOffset;
for (const auto& mark : marks)
{
const auto newY = mark.start.y;
if (newY > highest)
{
tgt = mark;
highest = newY;
}
}
break;
}
case ScrollToMarkDirection::First:
{
int lowest = currentOffset;
for (const auto& mark : marks)
{
const auto newY = mark.start.y;
if (newY < lowest)
{
tgt = mark;
lowest = newY;
}
}
break;
}
case ScrollToMarkDirection::Next:
{
int minDistance = INT_MAX;
for (const auto& mark : marks)
{
const auto delta = mark.start.y - currentOffset;
if (delta > 0 && delta < minDistance)
{
tgt = mark;
minDistance = delta;
}
}
break;
}
case ScrollToMarkDirection::Previous:
default:
{
int minDistance = INT_MAX;
for (const auto& mark : marks)
{
const auto delta = currentOffset - mark.start.y;
if (delta > 0 && delta < minDistance)
{
tgt = mark;
minDistance = delta;
}
}
break;
}
}

if (tgt.has_value())
{
UserScrollViewport(tgt->start.y);
}
else
{
if (direction == ScrollToMarkDirection::Last || direction == ScrollToMarkDirection::Next)
{
UserScrollViewport(BufferHeight());
}
else if (direction == ScrollToMarkDirection::First || direction == ScrollToMarkDirection::Previous)
{
UserScrollViewport(0);
}
}
}
}
7 changes: 7 additions & 0 deletions src/cascadia/TerminalControl/ControlCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
int BufferHeight() const;

bool BracketedPasteEnabled() const noexcept;

Windows::Foundation::Collections::IVector<Control::ScrollMark> ScrollMarks() const;
void AddMark(const Control::ScrollMark& mark);
void ClearMark();
void ClearAllMarks();
void ScrollToMark(const Control::ScrollToMarkDirection& direction);

#pragma endregion

#pragma region ITerminalInput
Expand Down
1 change: 0 additions & 1 deletion src/cascadia/TerminalControl/ControlCore.idl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ namespace Microsoft.Terminal.Control
IsRightButtonDown = 0x4
};


enum ClearBufferType
{
Screen,
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalControl/IControlSettings.idl
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ namespace Microsoft.Terminal.Control
// Experimental Settings
Boolean ForceFullRepaintRendering { get; };
Boolean SoftwareRendering { get; };
Boolean ShowMarks { get; };
Boolean UseBackgroundImageForWindow { get; };
};
}
32 changes: 32 additions & 0 deletions src/cascadia/TerminalControl/ICoreState.idl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,32 @@

namespace Microsoft.Terminal.Control
{
enum MarkCategory
{
Prompt = 0,
Error = 1,
Warning = 2,
Info = 3
};

struct ScrollMark
{
// There are other members of DispatchTypes::ScrollMark, but these are
// all we need to expose up and set downwards currently. Additional
// members can be bubbled as necessary.
Microsoft.Terminal.Core.Point Start;
Microsoft.Terminal.Core.Point End; // exclusive
Microsoft.Terminal.Core.OptionalColor Color;
};

enum ScrollToMarkDirection
{
Previous,
Next,
First,
Last
};

// These are properties of the TerminalCore that should be queryable by the
// rest of the app.
interface ICoreState
Expand All @@ -27,5 +53,11 @@ namespace Microsoft.Terminal.Control

UInt64 OwningHwnd;

void AddMark(ScrollMark mark);
void ClearMark();
void ClearAllMarks();
void ScrollToMark(ScrollToMarkDirection direction);
IVector<ScrollMark> ScrollMarks { get; };

};
}
Loading