Skip to content

Commit 0bafab9

Browse files
authored
Avoid covering current search highlight with search box (#17516)
## Summary of the Pull Request 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
1 parent f6a4155 commit 0bafab9

File tree

7 files changed

+52
-19
lines changed

7 files changed

+52
-19
lines changed

src/cascadia/TerminalControl/ControlCore.cpp

+9-10
Original file line numberDiff line numberDiff line change
@@ -1689,22 +1689,22 @@ namespace winrt::Microsoft::Terminal::Control::implementation
16891689
// - resetOnly: If true, only Reset() will be called, if anything. FindNext() will never be called.
16901690
// Return Value:
16911691
// - <none>
1692-
SearchResults ControlCore::Search(const std::wstring_view& text, const bool goForward, const bool caseSensitive, const bool regularExpression, const bool resetOnly)
1692+
SearchResults ControlCore::Search(SearchRequest request)
16931693
{
16941694
const auto lock = _terminal->LockForWriting();
16951695
SearchFlag flags{};
1696-
WI_SetFlagIf(flags, SearchFlag::CaseInsensitive, !caseSensitive);
1697-
WI_SetFlagIf(flags, SearchFlag::RegularExpression, regularExpression);
1698-
const auto searchInvalidated = _searcher.IsStale(*_terminal.get(), text, flags);
1696+
WI_SetFlagIf(flags, SearchFlag::CaseInsensitive, !request.CaseSensitive);
1697+
WI_SetFlagIf(flags, SearchFlag::RegularExpression, request.RegularExpression);
1698+
const auto searchInvalidated = _searcher.IsStale(*_terminal.get(), request.Text, flags);
16991699

1700-
if (searchInvalidated || !resetOnly)
1700+
if (searchInvalidated || !request.Reset)
17011701
{
17021702
std::vector<til::point_span> oldResults;
17031703

17041704
if (searchInvalidated)
17051705
{
17061706
oldResults = _searcher.ExtractResults();
1707-
_searcher.Reset(*_terminal.get(), text, flags, !goForward);
1707+
_searcher.Reset(*_terminal.get(), request.Text, flags, !request.GoForward);
17081708

17091709
if (SnapSearchResultToSelection())
17101710
{
@@ -1716,12 +1716,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
17161716
}
17171717
else
17181718
{
1719-
_searcher.FindNext(!goForward);
1719+
_searcher.FindNext(!request.GoForward);
17201720
}
17211721

17221722
if (const auto idx = _searcher.CurrentMatch(); idx >= 0)
17231723
{
1724-
_terminal->SetSearchHighlightFocused(gsl::narrow<size_t>(idx));
1724+
_terminal->SetSearchHighlightFocused(gsl::narrow<size_t>(idx), request.ScrollOffset);
17251725
}
17261726
_renderer->TriggerSearchHighlight(oldResults);
17271727
}
@@ -1751,7 +1751,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
17511751
{
17521752
const auto lock = _terminal->LockForWriting();
17531753
_terminal->SetSearchHighlights({});
1754-
_terminal->SetSearchHighlightFocused({});
1754+
_terminal->SetSearchHighlightFocused({}, 0);
17551755
_renderer->TriggerSearchHighlight(_searcher.Results());
17561756
_searcher = {};
17571757
}
@@ -2938,5 +2938,4 @@ namespace winrt::Microsoft::Terminal::Control::implementation
29382938
{
29392939
_terminal->PreviewText(input);
29402940
}
2941-
29422941
}

src/cascadia/TerminalControl/ControlCore.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
225225
void SetSelectionAnchor(const til::point position);
226226
void SetEndSelectionPoint(const til::point position);
227227

228-
SearchResults Search(const std::wstring_view& text, bool goForward, bool caseSensitive, bool regularExpression, bool reset);
228+
SearchResults Search(SearchRequest request);
229229
const std::vector<til::point_span>& SearchResultRows() const noexcept;
230230
void ClearSearch();
231231
void SnapSearchResultToSelection(bool snap) noexcept;

src/cascadia/TerminalControl/ControlCore.idl

+11-1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,16 @@ namespace Microsoft.Terminal.Control
4949
Boolean EndAtRightBoundary;
5050
};
5151

52+
struct SearchRequest
53+
{
54+
String Text;
55+
Boolean GoForward;
56+
Boolean CaseSensitive;
57+
Boolean RegularExpression;
58+
Boolean Reset;
59+
Int32 ScrollOffset;
60+
};
61+
5262
struct SearchResults
5363
{
5464
Int32 TotalMatches;
@@ -136,7 +146,7 @@ namespace Microsoft.Terminal.Control
136146
void ResumeRendering();
137147
void BlinkAttributeTick();
138148

139-
SearchResults Search(String text, Boolean goForward, Boolean caseSensitive, Boolean regularExpression, Boolean reset);
149+
SearchResults Search(SearchRequest request);
140150
void ClearSearch();
141151
Boolean SnapSearchResultToSelection;
142152

src/cascadia/TerminalControl/TermControl.cpp

+24-4
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
584584
_searchBox->Open([weakThis = get_weak()]() {
585585
if (const auto self = weakThis.get(); self && !self->_IsClosing())
586586
{
587+
self->_searchScrollOffset = self->_calculateSearchScrollOffset();
587588
self->_searchBox->SetFocusOnTextbox();
588589
self->_refreshSearch();
589590
}
@@ -605,7 +606,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
605606
}
606607
else
607608
{
608-
_handleSearchResults(_core.Search(_searchBox->Text(), goForward, _searchBox->CaseSensitive(), _searchBox->RegularExpression(), false));
609+
const auto request = SearchRequest{ _searchBox->Text(), goForward, _searchBox->CaseSensitive(), _searchBox->RegularExpression(), false, _searchScrollOffset };
610+
_handleSearchResults(_core.Search(request));
609611
}
610612
}
611613

@@ -639,7 +641,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
639641
{
640642
if (_searchBox && _searchBox->IsOpen())
641643
{
642-
_handleSearchResults(_core.Search(text, goForward, caseSensitive, regularExpression, false));
644+
const auto request = SearchRequest{ text, goForward, caseSensitive, regularExpression, false, _searchScrollOffset };
645+
_handleSearchResults(_core.Search(request));
643646
}
644647
}
645648

@@ -660,7 +663,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
660663
{
661664
// We only want to update the search results based on the new text. Set
662665
// `resetOnly` to true so we don't accidentally update the current match index.
663-
const auto result = _core.Search(text, goForward, caseSensitive, regularExpression, true);
666+
const auto request = SearchRequest{ text, goForward, caseSensitive, regularExpression, true, _searchScrollOffset };
667+
const auto result = _core.Search(request);
664668
_handleSearchResults(result);
665669
}
666670
}
@@ -3572,6 +3576,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
35723576
QuickFixIcon().FontSize(static_cast<double>(args.Width() / dpiScale));
35733577
RefreshQuickFixMenu();
35743578
}
3579+
3580+
_searchScrollOffset = _calculateSearchScrollOffset();
35753581
}
35763582

35773583
void TermControl::_coreRaisedNotice(const IInspectable& /*sender*/,
@@ -3702,7 +3708,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
37023708
const auto goForward = _searchBox->GoForward();
37033709
const auto caseSensitive = _searchBox->CaseSensitive();
37043710
const auto regularExpression = _searchBox->RegularExpression();
3705-
_handleSearchResults(_core.Search(text, goForward, caseSensitive, regularExpression, true));
3711+
const auto request = SearchRequest{ text, goForward, caseSensitive, regularExpression, true, _calculateSearchScrollOffset() };
3712+
_handleSearchResults(_core.Search(request));
37063713
}
37073714

37083715
void TermControl::_handleSearchResults(SearchResults results)
@@ -3982,6 +3989,19 @@ namespace winrt::Microsoft::Terminal::Control::implementation
39823989
SearchMissingCommand.raise(*this, args);
39833990
}
39843991

3992+
til::CoordType TermControl::_calculateSearchScrollOffset() const
3993+
{
3994+
auto result = 0;
3995+
if (_searchBox)
3996+
{
3997+
const auto displayInfo = DisplayInformation::GetForCurrentView();
3998+
const auto scaleFactor = _core.FontSize().Height / displayInfo.RawPixelsPerViewPixel();
3999+
const auto searchBoxRows = _searchBox->ActualHeight() / scaleFactor;
4000+
result = static_cast<int32_t>(std::ceil(searchBoxRows));
4001+
}
4002+
return result;
4003+
}
4004+
39854005
void TermControl::ClearQuickFix()
39864006
{
39874007
_core.ClearQuickFix();

src/cascadia/TerminalControl/TermControl.h

+2
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
289289

290290
bool _isBackgroundLight{ false };
291291
bool _detached{ false };
292+
til::CoordType _searchScrollOffset = 0;
292293

293294
Windows::Foundation::Collections::IObservableVector<Windows::UI::Xaml::Controls::ICommandBarElement> _originalPrimaryElements{ nullptr };
294295
Windows::Foundation::Collections::IObservableVector<Windows::UI::Xaml::Controls::ICommandBarElement> _originalSecondaryElements{ nullptr };
@@ -409,6 +410,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
409410
void _showContextMenuAt(const til::point& controlRelativePos);
410411

411412
void _bubbleSearchMissingCommand(const IInspectable& sender, const Control::SearchMissingCommandEventArgs& args);
413+
til::CoordType _calculateSearchScrollOffset() const;
412414

413415
void _PasteCommandHandler(const IInspectable& sender, const IInspectable& args);
414416
void _CopyCommandHandler(const IInspectable& sender, const IInspectable& args);

src/cascadia/TerminalCore/Terminal.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -1251,7 +1251,7 @@ void Terminal::SetSearchHighlights(const std::vector<til::point_span>& highlight
12511251
// Method Description:
12521252
// - Stores the focused search highlighted region in the terminal
12531253
// - If the region isn't empty, it will be brought into view
1254-
void Terminal::SetSearchHighlightFocused(const size_t focusedIdx)
1254+
void Terminal::SetSearchHighlightFocused(const size_t focusedIdx, til::CoordType searchScrollOffset)
12551255
{
12561256
_assertLocked();
12571257
_searchHighlightFocused = focusedIdx;
@@ -1260,7 +1260,9 @@ void Terminal::SetSearchHighlightFocused(const size_t focusedIdx)
12601260
if (focusedIdx < _searchHighlights.size())
12611261
{
12621262
const auto focused = til::at(_searchHighlights, focusedIdx);
1263-
_ScrollToPoints(focused.start, focused.end);
1263+
const auto adjustedStart = til::point{ focused.start.x, std::max(0, focused.start.y - searchScrollOffset) };
1264+
const auto adjustedEnd = til::point{ focused.end.x, std::max(0, focused.end.y - searchScrollOffset) };
1265+
_ScrollToPoints(adjustedStart, adjustedEnd);
12641266
}
12651267
}
12661268

src/cascadia/TerminalCore/Terminal.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ class Microsoft::Terminal::Core::Terminal final :
232232
void SetSearchMissingCommandCallback(std::function<void(std::wstring_view)> pfn) noexcept;
233233
void SetClearQuickFixCallback(std::function<void()> pfn) noexcept;
234234
void SetSearchHighlights(const std::vector<til::point_span>& highlights) noexcept;
235-
void SetSearchHighlightFocused(const size_t focusedIdx);
235+
void SetSearchHighlightFocused(const size_t focusedIdx, til::CoordType searchScrollOffset);
236236

237237
void BlinkCursor() noexcept;
238238
void SetCursorOn(const bool isOn) noexcept;

0 commit comments

Comments
 (0)