From 71409f84f7ac6ec94b55b6e00975467794e32ec0 Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Sat, 24 Jan 2026 01:33:18 +0100 Subject: [PATCH] Avoid scrolling when the search is open (#19775) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 ✅ --- src/cascadia/TerminalControl/ControlCore.cpp | 20 +++------ src/cascadia/TerminalControl/ControlCore.h | 2 +- src/cascadia/TerminalControl/ControlCore.idl | 3 +- src/cascadia/TerminalControl/TermControl.cpp | 47 +++++++++++++++----- 4 files changed, 46 insertions(+), 26 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index 8815169ba4..f5232ee1d7 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -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: // - - 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 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(std::max(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; diff --git a/src/cascadia/TerminalControl/ControlCore.h b/src/cascadia/TerminalControl/ControlCore.h index 99f13078c9..690f6fb465 100644 --- a/src/cascadia/TerminalControl/ControlCore.h +++ b/src/cascadia/TerminalControl/ControlCore.h @@ -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& SearchResultRows() const noexcept; void ClearSearch(); diff --git a/src/cascadia/TerminalControl/ControlCore.idl b/src/cascadia/TerminalControl/ControlCore.idl index d9f92e011b..c09fdf2d1a 100644 --- a/src/cascadia/TerminalControl/ControlCore.idl +++ b/src/cascadia/TerminalControl/ControlCore.idl @@ -55,7 +55,8 @@ namespace Microsoft.Terminal.Control Boolean GoForward; Boolean CaseSensitive; Boolean RegularExpression; - Boolean ResetOnly; + Boolean ExecuteSearch; + Boolean ScrollIntoView; Int32 ScrollOffset; }; diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index d3570ff1b5..dfbc7623c0 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -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)