mirror of
https://github.com/microsoft/terminal.git
synced 2025-12-10 00:48:23 -06:00
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:
parent
a7e2b46e20
commit
7c1e2298f8
@ -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();
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user