Fix some search highlights scenarios (#17352)

Fixes:
- Snapping the current match to the current selection doesn't work.
- Fast closing and re-opening SearchBox would leave search highlights in
an inconsistent state. The highlights would be active even when SB is
not on the screen, and results are not updated as more text is added to
the buffer.
- Search highlights scroll marks are not cleared when the search box is
closed.
This commit is contained in:
Tushar Singh 2024-06-13 23:59:12 +05:30 committed by GitHub
parent a7e2b46e20
commit 7c1e2298f8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 50 additions and 9 deletions

View File

@ -155,12 +155,18 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// search box remains in Visible state (though not really *visible*) during the
// first load. So, we only need to apply this check here (after checking that
// we're done initializing).
if (Visibility() == Visibility::Visible)
if (IsOpen())
{
callback();
return;
}
// Stop ongoing close animation if any
if (CloseAnimation().GetCurrentState() == Media::Animation::ClockState::Active)
{
CloseAnimation().Stop();
}
VisualStateManager::GoToState(*this, L"Opened", false);
// Call the callback only after we're in Opened state. Setting focus
@ -196,6 +202,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
}
bool SearchBoxControl::IsOpen()
{
return Visibility() == Visibility::Visible && CloseAnimation().GetCurrentState() != Media::Animation::ClockState::Active;
}
winrt::hstring SearchBoxControl::Text()
{
return TextBox().Text();

View File

@ -34,6 +34,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void TextBoxKeyDown(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::Windows::UI::Xaml::Input::KeyRoutedEventArgs& e);
void Open(std::function<void()> callback);
void Close();
bool IsOpen();
winrt::hstring Text();
bool GoForward();

View File

@ -493,7 +493,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
}
if (_searchBox && _searchBox->Visibility() == Visibility::Visible)
if (_searchBox && _searchBox->IsOpen())
{
const auto core = winrt::get_self<ControlCore>(_core);
const auto& searchMatches = core->SearchResultRows();
@ -538,6 +538,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// but since code paths differ, extra work is required to ensure correctness.
if (!_core.HasMultiLineSelection())
{
_core.SnapSearchResultToSelection(true);
const auto selectedLine{ _core.SelectedText(true) };
_searchBox->PopulateTextbox(selectedLine);
}
@ -554,13 +555,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
}
// This is called when a Find Next/Previous Match action is triggered.
void TermControl::SearchMatch(const bool goForward)
{
if (_IsClosing())
{
return;
}
if (!_searchBox || _searchBox->Visibility() != Visibility::Visible)
if (!_searchBox || !_searchBox->IsOpen())
{
CreateSearchBoxControl();
}
@ -598,11 +600,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
const bool caseSensitive,
const bool regularExpression)
{
_handleSearchResults(_core.Search(text, goForward, caseSensitive, regularExpression, false));
if (_searchBox && _searchBox->IsOpen())
{
_handleSearchResults(_core.Search(text, goForward, caseSensitive, regularExpression, false));
}
}
// Method Description:
// - The handler for the "search criteria changed" event. Clears selection and initiates a new search.
// - The handler for the "search criteria changed" event. Initiates a new search.
// Arguments:
// - text: the text to search
// - goForward: indicates whether the search should be performed forward (if set to true) or backward
@ -614,9 +619,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
const bool caseSensitive,
const bool regularExpression)
{
if (_searchBox && _searchBox->Visibility() == Visibility::Visible)
if (_searchBox && _searchBox->IsOpen())
{
_handleSearchResults(_core.Search(text, goForward, caseSensitive, regularExpression, false));
// 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);
_handleSearchResults(result);
}
}
@ -634,6 +642,19 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_searchBox->Close();
_core.ClearSearch();
// Clear search highlights scroll marks (by triggering an update after closing the search box)
if (_showMarksInScrollbar)
{
const auto scrollBar = ScrollBar();
ScrollBarUpdate update{
.newValue = scrollBar.Value(),
.newMaximum = scrollBar.Maximum(),
.newMinimum = scrollBar.Minimum(),
.newViewportSize = scrollBar.ViewportSize(),
};
_updateScrollBar->Run(update);
}
// Set focus back to terminal control
this->Focus(FocusState::Programmatic);
}
@ -3601,7 +3622,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void TermControl::_refreshSearch()
{
if (!_searchBox || _searchBox->Visibility() != Visibility::Visible)
if (!_searchBox || !_searchBox->IsOpen())
{
return;
}
@ -3625,7 +3646,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation
return;
}
_searchBox->SetStatus(results.TotalMatches, results.CurrentMatch, results.SearchRegexInvalid);
// Only show status when we have a search term
if (_searchBox->Text().empty())
{
_searchBox->ClearStatus();
}
else
{
_searchBox->SetStatus(results.TotalMatches, results.CurrentMatch, results.SearchRegexInvalid);
}
if (results.SearchInvalidated)
{