Skip to content

Commit

Permalink
Avoid covering current search highlight with search box (#17516)
Browse files Browse the repository at this point in the history
Adds a scroll offset to avoid hiding the current search highlight with
the search box.
- Offset is based on the number of rows that the search box takes up.
  (I am not totally sure I am calculating this right)
- This won't help when the current highlight is in the first couple
  rows of the buffer.

Fixes: #4407
(cherry picked from commit 0bafab9)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmszgTTNTE
Service-Version: 1.21
  • Loading branch information
e82eric authored and DHowett committed Sep 24, 2024
1 parent 87c87b5 commit d1ac375
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 18 deletions.
18 changes: 9 additions & 9 deletions src/cascadia/TerminalControl/ControlCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1654,22 +1654,22 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// - resetOnly: If true, only Reset() will be called, if anything. FindNext() will never be called.
// Return Value:
// - <none>
SearchResults ControlCore::Search(const std::wstring_view& text, const bool goForward, const bool caseSensitive, const bool regularExpression, const bool resetOnly)
SearchResults ControlCore::Search(SearchRequest request)
{
const auto lock = _terminal->LockForWriting();
SearchFlag flags{};
WI_SetFlagIf(flags, SearchFlag::CaseInsensitive, !caseSensitive);
WI_SetFlagIf(flags, SearchFlag::RegularExpression, regularExpression);
const auto searchInvalidated = _searcher.IsStale(*_terminal.get(), text, flags);
WI_SetFlagIf(flags, SearchFlag::CaseInsensitive, !request.CaseSensitive);
WI_SetFlagIf(flags, SearchFlag::RegularExpression, request.RegularExpression);
const auto searchInvalidated = _searcher.IsStale(*_terminal.get(), request.Text, flags);

if (searchInvalidated || !resetOnly)
if (searchInvalidated || !request.Reset)
{
std::vector<til::point_span> oldResults;

if (searchInvalidated)
{
oldResults = _searcher.ExtractResults();
_searcher.Reset(*_terminal.get(), text, flags, !goForward);
_searcher.Reset(*_terminal.get(), request.Text, flags, !request.GoForward);

if (SnapSearchResultToSelection())
{
Expand All @@ -1681,12 +1681,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
else
{
_searcher.FindNext(!goForward);
_searcher.FindNext(!request.GoForward);
}

if (const auto idx = _searcher.CurrentMatch(); idx >= 0)
{
_terminal->SetSearchHighlightFocused(gsl::narrow<size_t>(idx));
_terminal->SetSearchHighlightFocused(gsl::narrow<size_t>(idx), request.ScrollOffset);
}
_renderer->TriggerSearchHighlight(oldResults);
}
Expand Down Expand Up @@ -1716,7 +1716,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
{
const auto lock = _terminal->LockForWriting();
_terminal->SetSearchHighlights({});
_terminal->SetSearchHighlightFocused({});
_terminal->SetSearchHighlightFocused({}, 0);
_renderer->TriggerSearchHighlight(_searcher.Results());
_searcher = {};
}
Expand Down
2 changes: 1 addition & 1 deletion src/cascadia/TerminalControl/ControlCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void SetSelectionAnchor(const til::point position);
void SetEndSelectionPoint(const til::point position);

SearchResults Search(const std::wstring_view& text, bool goForward, bool caseSensitive, bool regularExpression, bool reset);
SearchResults Search(SearchRequest request);
const std::vector<til::point_span>& SearchResultRows() const noexcept;
void ClearSearch();
void SnapSearchResultToSelection(bool snap) noexcept;
Expand Down
12 changes: 11 additions & 1 deletion src/cascadia/TerminalControl/ControlCore.idl
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ namespace Microsoft.Terminal.Control
Boolean EndAtRightBoundary;
};

struct SearchRequest
{
String Text;
Boolean GoForward;
Boolean CaseSensitive;
Boolean RegularExpression;
Boolean Reset;
Int32 ScrollOffset;
};

struct SearchResults
{
Int32 TotalMatches;
Expand Down Expand Up @@ -135,7 +145,7 @@ namespace Microsoft.Terminal.Control
void ResumeRendering();
void BlinkAttributeTick();

SearchResults Search(String text, Boolean goForward, Boolean caseSensitive, Boolean regularExpression, Boolean reset);
SearchResults Search(SearchRequest request);
void ClearSearch();
Boolean SnapSearchResultToSelection;

Expand Down
28 changes: 24 additions & 4 deletions src/cascadia/TerminalControl/TermControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_searchBox->Open([weakThis = get_weak()]() {
if (const auto self = weakThis.get(); self && !self->_IsClosing())
{
self->_searchScrollOffset = self->_calculateSearchScrollOffset();
self->_searchBox->SetFocusOnTextbox();
self->_refreshSearch();
}
Expand All @@ -568,7 +569,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
else
{
_handleSearchResults(_core.Search(_searchBox->Text(), goForward, _searchBox->CaseSensitive(), _searchBox->RegularExpression(), false));
const auto request = SearchRequest{ _searchBox->Text(), goForward, _searchBox->CaseSensitive(), _searchBox->RegularExpression(), false, _searchScrollOffset };
_handleSearchResults(_core.Search(request));
}
}

Expand Down Expand Up @@ -602,7 +604,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
{
if (_searchBox && _searchBox->IsOpen())
{
_handleSearchResults(_core.Search(text, goForward, caseSensitive, regularExpression, false));
const auto request = SearchRequest{ text, goForward, caseSensitive, regularExpression, false, _searchScrollOffset };
_handleSearchResults(_core.Search(request));
}
}

Expand All @@ -623,7 +626,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
{
// We only want to update the search results based on the new text. Set
// `resetOnly` to true so we don't accidentally update the current match index.
const auto result = _core.Search(text, goForward, caseSensitive, regularExpression, true);
const auto request = SearchRequest{ text, goForward, caseSensitive, regularExpression, true, _searchScrollOffset };
const auto result = _core.Search(request);
_handleSearchResults(result);
}
}
Expand Down Expand Up @@ -3629,6 +3633,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
};
scaleMarker(SelectionStartMarker());
scaleMarker(SelectionEndMarker());

_searchScrollOffset = _calculateSearchScrollOffset();
}

void TermControl::_coreRaisedNotice(const IInspectable& /*sender*/,
Expand Down Expand Up @@ -3750,7 +3756,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
const auto goForward = _searchBox->GoForward();
const auto caseSensitive = _searchBox->CaseSensitive();
const auto regularExpression = _searchBox->RegularExpression();
_handleSearchResults(_core.Search(text, goForward, caseSensitive, regularExpression, true));
const auto request = SearchRequest{ text, goForward, caseSensitive, regularExpression, true, _calculateSearchScrollOffset() };
_handleSearchResults(_core.Search(request));
}

void TermControl::_handleSearchResults(SearchResults results)
Expand Down Expand Up @@ -3919,6 +3926,19 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_showContextMenuAt(_toControlOrigin(cursorPos));
}

til::CoordType TermControl::_calculateSearchScrollOffset() const
{
auto result = 0;
if (_searchBox)
{
const auto displayInfo = DisplayInformation::GetForCurrentView();
const auto scaleFactor = _core.FontSize().Height / displayInfo.RawPixelsPerViewPixel();
const auto searchBoxRows = _searchBox->ActualHeight() / scaleFactor;
result = static_cast<int32_t>(std::ceil(searchBoxRows));
}
return result;
}

void TermControl::_PasteCommandHandler(const IInspectable& /*sender*/,
const IInspectable& /*args*/)
{
Expand Down
3 changes: 3 additions & 0 deletions src/cascadia/TerminalControl/TermControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation

bool _isBackgroundLight{ false };
bool _detached{ false };
til::CoordType _searchScrollOffset = 0;

Windows::Foundation::Collections::IObservableVector<Windows::UI::Xaml::Controls::ICommandBarElement> _originalPrimaryElements{ nullptr };
Windows::Foundation::Collections::IObservableVector<Windows::UI::Xaml::Controls::ICommandBarElement> _originalSecondaryElements{ nullptr };
Expand Down Expand Up @@ -420,6 +421,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void _contextMenuHandler(IInspectable sender, Control::ContextMenuRequestedEventArgs args);
void _showContextMenuAt(const til::point& controlRelativePos);

til::CoordType _calculateSearchScrollOffset() const;

void _PasteCommandHandler(const IInspectable& sender, const IInspectable& args);
void _CopyCommandHandler(const IInspectable& sender, const IInspectable& args);
void _SearchCommandHandler(const IInspectable& sender, const IInspectable& args);
Expand Down
6 changes: 4 additions & 2 deletions src/cascadia/TerminalCore/Terminal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1238,7 +1238,7 @@ void Terminal::SetSearchHighlights(const std::vector<til::point_span>& highlight
// Method Description:
// - Stores the focused search highlighted region in the terminal
// - If the region isn't empty, it will be brought into view
void Terminal::SetSearchHighlightFocused(const size_t focusedIdx)
void Terminal::SetSearchHighlightFocused(const size_t focusedIdx, til::CoordType searchScrollOffset)
{
_assertLocked();
_searchHighlightFocused = focusedIdx;
Expand All @@ -1247,7 +1247,9 @@ void Terminal::SetSearchHighlightFocused(const size_t focusedIdx)
if (focusedIdx < _searchHighlights.size())
{
const auto focused = til::at(_searchHighlights, focusedIdx);
_ScrollToPoints(focused.start, focused.end);
const auto adjustedStart = til::point{ focused.start.x, std::max(0, focused.start.y - searchScrollOffset) };
const auto adjustedEnd = til::point{ focused.end.x, std::max(0, focused.end.y - searchScrollOffset) };
_ScrollToPoints(adjustedStart, adjustedEnd);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/cascadia/TerminalCore/Terminal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ class Microsoft::Terminal::Core::Terminal final :
void SetPlayMidiNoteCallback(std::function<void(const int, const int, const std::chrono::microseconds)> pfn) noexcept;
void CompletionsChangedCallback(std::function<void(std::wstring_view, unsigned int)> pfn) noexcept;
void SetSearchHighlights(const std::vector<til::point_span>& highlights) noexcept;
void SetSearchHighlightFocused(const size_t focusedIdx);
void SetSearchHighlightFocused(const size_t focusedIdx, til::CoordType searchScrollOffset);

void BlinkCursor() noexcept;
void SetCursorOn(const bool isOn) noexcept;
Expand Down

0 comments on commit d1ac375

Please sign in to comment.