diff --git a/src/cascadia/TerminalControl/SearchBoxControl.cpp b/src/cascadia/TerminalControl/SearchBoxControl.cpp index 46e27de04d..0a63da28c0 100644 --- a/src/cascadia/TerminalControl/SearchBoxControl.cpp +++ b/src/cascadia/TerminalControl/SearchBoxControl.cpp @@ -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(); diff --git a/src/cascadia/TerminalControl/SearchBoxControl.h b/src/cascadia/TerminalControl/SearchBoxControl.h index d774e42b56..ab6af68c4e 100644 --- a/src/cascadia/TerminalControl/SearchBoxControl.h +++ b/src/cascadia/TerminalControl/SearchBoxControl.h @@ -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 callback); void Close(); + bool IsOpen(); winrt::hstring Text(); bool GoForward(); diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index bdc6f42061..1fffe66dc5 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -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(_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) {