Avoid scrolling when the search is open (#19775)

When text scrolls in and out of view, depending on the length
of the scrollback and latency of input, `GetSearchHighlightFocused`
would change which would trigger a `ScrollToSearchHighlight` call.

This PR changes the behavior such that only actively changing the
search mask triggers a search (typing text or pressing enter).

Closes #19754

## Validation Steps Performed
* Brining text in and out of view doesn't scroll 
* Toggling the aA button scrolls results into view 
This commit is contained in:
Leonard Hecker 2026-01-24 01:33:18 +01:00 committed by GitHub
parent 6723ca2239
commit 71409f84f7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 46 additions and 26 deletions

View File

@ -1736,7 +1736,7 @@ 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(SearchRequest request)
SearchResults ControlCore::Search(const SearchRequest& request)
{
const auto lock = _terminal->LockForWriting();
@ -1745,15 +1745,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
WI_SetFlagIf(flags, SearchFlag::RegularExpression, request.RegularExpression);
const auto searchInvalidated = _searcher.IsStale(*_terminal.get(), request.Text, flags);
if (searchInvalidated || !request.ResetOnly)
if (searchInvalidated || request.ExecuteSearch)
{
std::vector<til::point_span> oldResults;
til::point_span oldFocused;
if (const auto focused = _terminal->GetSearchHighlightFocused())
{
oldFocused = *focused;
}
if (searchInvalidated)
{
@ -1762,18 +1756,18 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_terminal->SetSearchHighlights(_searcher.Results());
}
if (!request.ResetOnly)
if (request.ExecuteSearch)
{
_searcher.FindNext(!request.GoForward);
}
_terminal->SetSearchHighlightFocused(gsl::narrow<size_t>(std::max<ptrdiff_t>(0, _searcher.CurrentMatch())));
_renderer->TriggerSearchHighlight(oldResults);
}
if (const auto focused = _terminal->GetSearchHighlightFocused(); focused && *focused != oldFocused)
{
_terminal->ScrollToSearchHighlight(request.ScrollOffset);
}
if (request.ScrollIntoView)
{
_terminal->ScrollToSearchHighlight(request.ScrollOffset);
}
int32_t totalMatches = 0;

View File

@ -225,7 +225,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void SetSelectionAnchor(const til::point position);
void SetEndSelectionPoint(const til::point position);
SearchResults Search(SearchRequest request);
SearchResults Search(const SearchRequest& request);
const std::vector<til::point_span>& SearchResultRows() const noexcept;
void ClearSearch();

View File

@ -55,7 +55,8 @@ namespace Microsoft.Terminal.Control
Boolean GoForward;
Boolean CaseSensitive;
Boolean RegularExpression;
Boolean ResetOnly;
Boolean ExecuteSearch;
Boolean ScrollIntoView;
Int32 ScrollOffset;
};

View File

@ -714,8 +714,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
else
{
const auto request = SearchRequest{ _searchBox->Text(), goForward, _searchBox->CaseSensitive(), _searchBox->RegularExpression(), false, _searchScrollOffset };
_handleSearchResults(_core.Search(request));
_handleSearchResults(_core.Search(SearchRequest{
.Text = _searchBox->Text(),
.GoForward = goForward,
.CaseSensitive = _searchBox->CaseSensitive(),
.RegularExpression = _searchBox->RegularExpression(),
.ExecuteSearch = true,
.ScrollIntoView = true,
.ScrollOffset = _searchScrollOffset,
}));
}
}
@ -749,8 +756,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation
{
if (_searchBox && _searchBox->IsOpen())
{
const auto request = SearchRequest{ text, goForward, caseSensitive, regularExpression, false, _searchScrollOffset };
_handleSearchResults(_core.Search(request));
_handleSearchResults(_core.Search(SearchRequest{
.Text = text,
.GoForward = goForward,
.CaseSensitive = caseSensitive,
.RegularExpression = regularExpression,
.ExecuteSearch = true,
.ScrollIntoView = true,
.ScrollOffset = _searchScrollOffset,
}));
}
}
@ -769,11 +783,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation
{
if (_searchBox && _searchBox->IsOpen())
{
// 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 request = SearchRequest{ text, goForward, caseSensitive, regularExpression, true, _searchScrollOffset };
const auto result = _core.Search(request);
_handleSearchResults(result);
_handleSearchResults(_core.Search(SearchRequest{
.Text = text,
.GoForward = goForward,
.CaseSensitive = caseSensitive,
.RegularExpression = regularExpression,
.ExecuteSearch = false,
.ScrollIntoView = true,
.ScrollOffset = _searchScrollOffset,
}));
}
}
@ -3742,8 +3760,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation
const auto goForward = _searchBox->GoForward();
const auto caseSensitive = _searchBox->CaseSensitive();
const auto regularExpression = _searchBox->RegularExpression();
const auto request = SearchRequest{ text, goForward, caseSensitive, regularExpression, true, _searchScrollOffset };
_handleSearchResults(_core.Search(request));
_handleSearchResults(_core.Search(SearchRequest{
.Text = text,
.GoForward = goForward,
.CaseSensitive = caseSensitive,
.RegularExpression = regularExpression,
.ExecuteSearch = false,
.ScrollIntoView = false,
.ScrollOffset = _searchScrollOffset,
}));
}
void TermControl::_handleSearchResults(SearchResults results)