diff --git a/src/buffer/out/search.cpp b/src/buffer/out/search.cpp index 336fa2957fb..08ed8ad2ef7 100644 --- a/src/buffer/out/search.cpp +++ b/src/buffer/out/search.cpp @@ -13,7 +13,8 @@ bool Search::ResetIfStale(Microsoft::Console::Render::IRenderData& renderData, c const auto& textBuffer = renderData.GetTextBuffer(); const auto lastMutationId = textBuffer.GetLastMutationId(); - if (_needle == needle && + if (_renderData == &renderData && + _needle == needle && _caseInsensitive == caseInsensitive && _lastMutationId == lastMutationId) { @@ -21,15 +22,16 @@ bool Search::ResetIfStale(Microsoft::Console::Render::IRenderData& renderData, c return false; } + if (prevResults) + { + *prevResults = std::move(_results); + } + _renderData = &renderData; _needle = needle; _caseInsensitive = caseInsensitive; _lastMutationId = lastMutationId; - if (prevResults) - { - *prevResults = std::move(_results); - } _results = textBuffer.SearchText(needle, caseInsensitive); _index = reverse ? gsl::narrow_cast(_results.size()) - 1 : 0; _step = reverse ? -1 : 1; @@ -142,4 +144,4 @@ const std::vector& Search::Results() const noexcept ptrdiff_t Search::CurrentMatch() const noexcept { return _index; -} \ No newline at end of file +} diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index cfba0a1d46a..1e82b825eb0 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -29,19 +29,6 @@ using namespace winrt::Windows::Graphics::Display; using namespace winrt::Windows::System; using namespace winrt::Windows::ApplicationModel::DataTransfer; -// The minimum delay between updates to the scroll bar's values. -// The updates are throttled to limit power usage. -constexpr const auto ScrollBarUpdateInterval = std::chrono::milliseconds(8); - -// The minimum delay between updating the TSF input control. -constexpr const auto TsfRedrawInterval = std::chrono::milliseconds(100); - -// The minimum delay between updating the locations of regex patterns -constexpr const auto UpdatePatternLocationsInterval = std::chrono::milliseconds(500); - -// The delay before performing the search after change of search criteria -constexpr const auto SearchAfterChangeDelay = std::chrono::milliseconds(200); - namespace winrt::Microsoft::Terminal::Control::implementation { static winrt::Microsoft::Terminal::Core::OptionalColor OptionalFromColor(const til::color& c) noexcept @@ -117,9 +104,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation auto pfnShowWindowChanged = std::bind(&ControlCore::_terminalShowWindowChanged, this, std::placeholders::_1); _terminal->SetShowWindowCallback(pfnShowWindowChanged); - auto pfnTextLayoutUpdated = std::bind(&ControlCore::_terminalTextLayoutUpdated, this); - _terminal->SetTextLayoutUpdatedCallback(pfnTextLayoutUpdated); - auto pfnPlayMidiNote = std::bind(&ControlCore::_terminalPlayMidiNote, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); _terminal->SetPlayMidiNoteCallback(pfnPlayMidiNote); @@ -167,21 +151,22 @@ namespace winrt::Microsoft::Terminal::Control::implementation _dispatcher = controller.DispatcherQueue(); } - // A few different events should be throttled, so they don't fire absolutely all the time: - // * _updatePatternLocations: When there's new output, or we scroll the - // viewport, we should re-check if there are any visible hyperlinks. - // But we don't really need to do this every single time text is - // output, we can limit this update to once every 500ms. - // * _updateScrollBar: Same idea as the TSF update - we don't _really_ - // need to hop across the process boundary every time text is output. - // We can throttle this to once every 8ms, which will get us out of - // the way of the main output & rendering threads. const auto shared = _shared.lock(); + // Raises an OutputIdle event once there hasn't been any output for at least 100ms. + // It also updates all regex patterns in the viewport. + // // NOTE: Calling UpdatePatternLocations from a background // thread is a workaround for us to hit GH#12607 less often. - shared->updatePatternLocations = std::make_unique>( - UpdatePatternLocationsInterval, - [weakTerminal = std::weak_ptr{ _terminal }]() { + shared->outputIdle = std::make_unique>( + std::chrono::milliseconds{ 100 }, + [weakTerminal = std::weak_ptr{ _terminal }, weakThis = get_weak(), dispatcher = _dispatcher]() { + dispatcher.TryEnqueue(DispatcherQueuePriority::Normal, [weakThis]() { + if (const auto self = weakThis.get(); !self->_IsClosing()) + { + self->OutputIdle.raise(*self, nullptr); + } + }); + if (const auto t = weakTerminal.lock()) { const auto lock = t->LockForWriting(); @@ -189,9 +174,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation } }); + // Scrollbar updates are also expensive (XAML), so we'll throttle them as well. shared->updateScrollBar = std::make_shared>( _dispatcher, - ScrollBarUpdateInterval, + std::chrono::milliseconds{ 8 }, [weakThis = get_weak()](const auto& update) { if (auto core{ weakThis.get() }; !core->_IsClosing()) { @@ -218,7 +204,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // thread. These will be recreated in _setupDispatcherAndCallbacks, when // we're re-attached to a new control (on a possibly new UI thread). const auto shared = _shared.lock(); - shared->updatePatternLocations.reset(); + shared->outputIdle.reset(); shared->updateScrollBar.reset(); } @@ -671,9 +657,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation } const auto shared = _shared.lock_shared(); - if (shared->updatePatternLocations) + if (shared->outputIdle) { - (*shared->updatePatternLocations)(); + (*shared->outputIdle)(); } } @@ -1100,12 +1086,20 @@ namespace winrt::Microsoft::Terminal::Control::implementation // If this function succeeds with S_FALSE, then the terminal didn't // actually change size. No need to notify the connection of this no-op. const auto hr = _terminal->UserResize({ vp.Width(), vp.Height() }); - if (SUCCEEDED(hr) && hr != S_FALSE) + if (FAILED(hr) || hr == S_FALSE) { - _connection.Resize(vp.Height(), vp.Width()); + return; + } + + _connection.Resize(vp.Height(), vp.Width()); - // let the UI know that the text layout has been updated - _terminal->NotifyTextLayoutUpdated(); + // TermControl will call Search() once the OutputIdle even fires after 100ms. + // Until then we need to hide the now-stale search results from the renderer. + ClearSearch(); + const auto shared = _shared.lock_shared(); + if (shared->outputIdle) + { + (*shared->outputIdle)(); } } @@ -1603,16 +1597,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation ShowWindowChanged.raise(*this, *showWindow); } - void ControlCore::_terminalTextLayoutUpdated() - { - ClearSearch(); - - // send an UpdateSearchResults event to the UI to put the Search UI into inactive state. - auto evArgs = winrt::make_self(); - evArgs->State(SearchState::Inactive); - UpdateSearchResults.raise(*this, *evArgs); - } - // Method Description: // - Plays a single MIDI note, blocking for the duration. // Arguments: @@ -1672,13 +1656,16 @@ namespace winrt::Microsoft::Terminal::Control::implementation // - caseSensitive: boolean that represents if the current search is case sensitive // Return Value: // - - void ControlCore::Search(const winrt::hstring& text, const bool goForward, const bool caseSensitive) + SearchResults ControlCore::Search(const std::wstring_view& text, const bool goForward, const bool caseSensitive, const bool reset) { const auto lock = _terminal->LockForWriting(); + bool searchInvalidated = false; std::vector oldResults; if (_searcher.ResetIfStale(*GetRenderData(), text, !goForward, !caseSensitive, &oldResults)) { + searchInvalidated = true; + _cachedSearchResultRows = {}; if (SnapSearchResultToSelection()) { @@ -1687,30 +1674,28 @@ namespace winrt::Microsoft::Terminal::Control::implementation } _terminal->SetSearchHighlights(_searcher.Results()); - _terminal->SetSearchHighlightFocused(_searcher.CurrentMatch()); } - else + else if (!reset) { _searcher.FindNext(); - _terminal->SetSearchHighlightFocused(_searcher.CurrentMatch()); } - _renderer->TriggerSearchHighlight(oldResults); - auto evArgs = winrt::make_self(); - if (!text.empty()) + int32_t totalMatches = 0; + int32_t currentMatch = 0; + if (const auto idx = _searcher.CurrentMatch(); idx >= 0) { - evArgs->State(SearchState::Active); - if (_searcher.GetCurrent()) - { - evArgs->FoundMatch(true); - evArgs->TotalMatches(gsl::narrow(_searcher.Results().size())); - evArgs->CurrentMatch(gsl::narrow(_searcher.CurrentMatch())); - } + totalMatches = gsl::narrow(_searcher.Results().size()); + currentMatch = gsl::narrow(idx); + _terminal->SetSearchHighlightFocused(gsl::narrow(idx)); } - // Raise an UpdateSearchResults event, which the control will use to update the - // UI and notify the narrator about the updated search results in the buffer - UpdateSearchResults.raise(*this, *evArgs); + _renderer->TriggerSearchHighlight(oldResults); + + return { + .TotalMatches = totalMatches, + .CurrentMatch = currentMatch, + .SearchInvalidated = searchInvalidated, + }; } Windows::Foundation::Collections::IVector ControlCore::SearchResultRows() @@ -1738,16 +1723,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation void ControlCore::ClearSearch() { - // nothing to clear if there's no results - if (_searcher.GetCurrent()) - { - const auto lock = _terminal->LockForWriting(); - _terminal->SetSearchHighlights({}); - _terminal->SetSearchHighlightFocused({}); - _renderer->TriggerSearchHighlight(_searcher.Results()); - _searcher = {}; - _cachedSearchResultRows = {}; - } + const auto lock = _terminal->LockForWriting(); + _terminal->SetSearchHighlights({}); + _terminal->SetSearchHighlightFocused({}); + _renderer->TriggerSearchHighlight(_searcher.Results()); + _searcher = {}; + _cachedSearchResultRows = {}; } // Method Description: @@ -2130,9 +2111,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation // Start the throttled update of where our hyperlinks are. const auto shared = _shared.lock_shared(); - if (shared->updatePatternLocations) + if (shared->outputIdle) { - (*shared->updatePatternLocations)(); + (*shared->outputIdle)(); } } catch (...) diff --git a/src/cascadia/TerminalControl/ControlCore.h b/src/cascadia/TerminalControl/ControlCore.h index ee2e1e5a841..adcaf821024 100644 --- a/src/cascadia/TerminalControl/ControlCore.h +++ b/src/cascadia/TerminalControl/ControlCore.h @@ -219,7 +219,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation void SetSelectionAnchor(const til::point position); void SetEndSelectionPoint(const til::point position); - void Search(const winrt::hstring& text, const bool goForward, const bool caseSensitive); + SearchResults Search(const std::wstring_view& text, bool goForward, bool caseSensitive, bool reset); void ClearSearch(); void SnapSearchResultToSelection(bool snap) noexcept; bool SnapSearchResultToSelection() const noexcept; @@ -279,8 +279,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation til::typed_event RendererWarning; til::typed_event RaiseNotice; til::typed_event TransparencyChanged; - til::typed_event<> ReceivedOutput; - til::typed_event UpdateSearchResults; + til::typed_event<> OutputIdle; til::typed_event ShowWindowChanged; til::typed_event UpdateSelectionMarkers; til::typed_event OpenHyperlink; @@ -295,7 +294,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation private: struct SharedState { - std::unique_ptr> updatePatternLocations; + std::unique_ptr> outputIdle; std::shared_ptr> updateScrollBar; }; @@ -376,7 +375,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation const int bufferSize); void _terminalTaskbarProgressChanged(); void _terminalShowWindowChanged(bool showOrHide); - void _terminalTextLayoutUpdated(); void _terminalPlayMidiNote(const int noteNumber, const int velocity, const std::chrono::microseconds duration); diff --git a/src/cascadia/TerminalControl/ControlCore.idl b/src/cascadia/TerminalControl/ControlCore.idl index 038f21c0f41..ac5eed73452 100644 --- a/src/cascadia/TerminalControl/ControlCore.idl +++ b/src/cascadia/TerminalControl/ControlCore.idl @@ -49,6 +49,13 @@ namespace Microsoft.Terminal.Control Boolean EndAtRightBoundary; }; + struct SearchResults + { + Int32 TotalMatches; + Int32 CurrentMatch; + Boolean SearchInvalidated; + }; + [default_interface] runtimeclass SelectionColor { SelectionColor(); @@ -127,7 +134,7 @@ namespace Microsoft.Terminal.Control void ResumeRendering(); void BlinkAttributeTick(); - void Search(String text, Boolean goForward, Boolean caseSensitive); + SearchResults Search(String text, Boolean goForward, Boolean caseSensitive, Boolean reset); void ClearSearch(); IVector SearchResultRows { get; }; Boolean SnapSearchResultToSelection; @@ -177,8 +184,7 @@ namespace Microsoft.Terminal.Control event Windows.Foundation.TypedEventHandler RendererWarning; event Windows.Foundation.TypedEventHandler RaiseNotice; event Windows.Foundation.TypedEventHandler TransparencyChanged; - event Windows.Foundation.TypedEventHandler ReceivedOutput; - event Windows.Foundation.TypedEventHandler UpdateSearchResults; + event Windows.Foundation.TypedEventHandler OutputIdle; event Windows.Foundation.TypedEventHandler UpdateSelectionMarkers; event Windows.Foundation.TypedEventHandler OpenHyperlink; event Windows.Foundation.TypedEventHandler CloseTerminalRequested; diff --git a/src/cascadia/TerminalControl/EventArgs.cpp b/src/cascadia/TerminalControl/EventArgs.cpp index 4c4d1690953..fb69e9e0541 100644 --- a/src/cascadia/TerminalControl/EventArgs.cpp +++ b/src/cascadia/TerminalControl/EventArgs.cpp @@ -12,7 +12,6 @@ #include "ScrollPositionChangedArgs.g.cpp" #include "RendererWarningArgs.g.cpp" #include "TransparencyChangedEventArgs.g.cpp" -#include "UpdateSearchResultsEventArgs.g.cpp" #include "ShowWindowArgs.g.cpp" #include "UpdateSelectionMarkersEventArgs.g.cpp" #include "CompletionsChangedEventArgs.g.cpp" diff --git a/src/cascadia/TerminalControl/EventArgs.h b/src/cascadia/TerminalControl/EventArgs.h index d8990c6f212..423e5695d73 100644 --- a/src/cascadia/TerminalControl/EventArgs.h +++ b/src/cascadia/TerminalControl/EventArgs.h @@ -12,7 +12,6 @@ #include "ScrollPositionChangedArgs.g.h" #include "RendererWarningArgs.g.h" #include "TransparencyChangedEventArgs.g.h" -#include "UpdateSearchResultsEventArgs.g.h" #include "ShowWindowArgs.g.h" #include "UpdateSelectionMarkersEventArgs.g.h" #include "CompletionsChangedEventArgs.g.h" @@ -141,17 +140,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation WINRT_PROPERTY(float, Opacity); }; - struct UpdateSearchResultsEventArgs : public UpdateSearchResultsEventArgsT - { - public: - UpdateSearchResultsEventArgs() = default; - - WINRT_PROPERTY(SearchState, State, SearchState::Inactive); - WINRT_PROPERTY(bool, FoundMatch); - WINRT_PROPERTY(int32_t, TotalMatches); - WINRT_PROPERTY(int32_t, CurrentMatch); - }; - struct ShowWindowArgs : public ShowWindowArgsT { public: diff --git a/src/cascadia/TerminalControl/EventArgs.idl b/src/cascadia/TerminalControl/EventArgs.idl index d04044073e8..6b0bf11e359 100644 --- a/src/cascadia/TerminalControl/EventArgs.idl +++ b/src/cascadia/TerminalControl/EventArgs.idl @@ -84,14 +84,6 @@ namespace Microsoft.Terminal.Control Active = 1, }; - runtimeclass UpdateSearchResultsEventArgs - { - SearchState State { get; }; - Boolean FoundMatch { get; }; - Int32 TotalMatches { get; }; - Int32 CurrentMatch { get; }; - } - runtimeclass ShowWindowArgs { Boolean ShowOrHide { get; }; diff --git a/src/cascadia/TerminalControl/SearchBoxControl.cpp b/src/cascadia/TerminalControl/SearchBoxControl.cpp index 9ce4bba86a8..eaaae04add9 100644 --- a/src/cascadia/TerminalControl/SearchBoxControl.cpp +++ b/src/cascadia/TerminalControl/SearchBoxControl.cpp @@ -195,6 +195,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation } } + winrt::hstring SearchBoxControl::Text() + { + return TextBox().Text(); + } + // Method Description: // - Check if the current search direction is forward // Arguments: @@ -202,7 +207,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // Return Value: // - bool: the current search direction, determined by the // states of the two direction buttons - bool SearchBoxControl::_GoForward() + bool SearchBoxControl::GoForward() { return GoForwardButton().IsChecked().GetBoolean(); } @@ -214,7 +219,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // Return Value: // - bool: whether the current search is case sensitive (case button is checked ) // or not - bool SearchBoxControl::_CaseSensitive() + bool SearchBoxControl::CaseSensitive() { return CaseSensitivityButton().IsChecked().GetBoolean(); } @@ -240,11 +245,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation const auto state = CoreWindow::GetForCurrentThread().GetKeyState(winrt::Windows::System::VirtualKey::Shift); if (WI_IsFlagSet(state, CoreVirtualKeyStates::Down)) { - Search.raise(TextBox().Text(), !_GoForward(), _CaseSensitive()); + Search.raise(Text(), !GoForward(), CaseSensitive()); } else { - Search.raise(TextBox().Text(), _GoForward(), _CaseSensitive()); + Search.raise(Text(), GoForward(), CaseSensitive()); } e.Handled(true); } @@ -335,7 +340,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation } // kick off search - Search.raise(TextBox().Text(), _GoForward(), _CaseSensitive()); + Search.raise(Text(), GoForward(), CaseSensitive()); } // Method Description: @@ -356,7 +361,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation } // kick off search - Search.raise(TextBox().Text(), _GoForward(), _CaseSensitive()); + Search.raise(Text(), GoForward(), CaseSensitive()); } // Method Description: @@ -394,7 +399,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // - void SearchBoxControl::TextBoxTextChanged(winrt::Windows::Foundation::IInspectable const& /*sender*/, winrt::Windows::UI::Xaml::RoutedEventArgs const& /*e*/) { - SearchChanged.raise(TextBox().Text(), _GoForward(), _CaseSensitive()); + SearchChanged.raise(Text(), GoForward(), CaseSensitive()); } // Method Description: @@ -406,7 +411,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // - void SearchBoxControl::CaseSensitivityButtonClicked(winrt::Windows::Foundation::IInspectable const& /*sender*/, winrt::Windows::UI::Xaml::RoutedEventArgs const& /*e*/) { - SearchChanged.raise(TextBox().Text(), _GoForward(), _CaseSensitive()); + SearchChanged.raise(Text(), GoForward(), CaseSensitive()); } // Method Description: @@ -528,20 +533,4 @@ namespace winrt::Microsoft::Terminal::Control::implementation { StatusBox().Text(L""); } - - // Method Description: - // - Enables / disables results navigation buttons - // Arguments: - // - enable: if true, the buttons should be enabled - // Return Value: - // - - void SearchBoxControl::NavigationEnabled(bool enabled) - { - GoBackwardButton().IsEnabled(enabled); - GoForwardButton().IsEnabled(enabled); - } - bool SearchBoxControl::NavigationEnabled() - { - return GoBackwardButton().IsEnabled() || GoForwardButton().IsEnabled(); - } } diff --git a/src/cascadia/TerminalControl/SearchBoxControl.h b/src/cascadia/TerminalControl/SearchBoxControl.h index 53a738c399e..60ea00da481 100644 --- a/src/cascadia/TerminalControl/SearchBoxControl.h +++ b/src/cascadia/TerminalControl/SearchBoxControl.h @@ -35,13 +35,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation void Open(std::function callback); void Close(); + winrt::hstring Text(); + bool GoForward(); + bool CaseSensitive(); void SetFocusOnTextbox(); void PopulateTextbox(const winrt::hstring& text); bool ContainsFocus(); void SetStatus(int32_t totalMatches, int32_t currentMatch); void ClearStatus(); - bool NavigationEnabled(); - void NavigationEnabled(bool enabled); void GoBackwardClicked(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::Windows::UI::Xaml::RoutedEventArgs& /*e*/); void GoForwardClicked(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::Windows::UI::Xaml::RoutedEventArgs& /*e*/); @@ -77,8 +78,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation static double _TextWidth(winrt::hstring text, double fontSize); double _GetStatusMaxWidth(); - bool _GoForward(); - bool _CaseSensitive(); void _KeyDownHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::Input::KeyRoutedEventArgs& e); void _CharacterHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::Windows::UI::Xaml::Input::CharacterReceivedRoutedEventArgs& e); }; diff --git a/src/cascadia/TerminalControl/SearchBoxControl.idl b/src/cascadia/TerminalControl/SearchBoxControl.idl index 42abd1fa1b3..3abf4f50229 100644 --- a/src/cascadia/TerminalControl/SearchBoxControl.idl +++ b/src/cascadia/TerminalControl/SearchBoxControl.idl @@ -16,8 +16,6 @@ namespace Microsoft.Terminal.Control Windows.Foundation.Rect ContentClipRect{ get; }; Double OpenAnimationStartPoint{ get; }; - Boolean NavigationEnabled; - event SearchHandler Search; event SearchHandler SearchChanged; event Windows.Foundation.TypedEventHandler Closed; diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 81934f10f65..22efc0b18e2 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -204,7 +204,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation _revokers.TransparencyChanged = _core.TransparencyChanged(winrt::auto_revoke, { get_weak(), &TermControl::_coreTransparencyChanged }); _revokers.RaiseNotice = _core.RaiseNotice(winrt::auto_revoke, { get_weak(), &TermControl::_coreRaisedNotice }); _revokers.HoveredHyperlinkChanged = _core.HoveredHyperlinkChanged(winrt::auto_revoke, { get_weak(), &TermControl::_hoveredHyperlinkChanged }); - _revokers.UpdateSearchResults = _core.UpdateSearchResults(winrt::auto_revoke, { get_weak(), &TermControl::_coreUpdateSearchResults }); + _revokers.OutputIdle = _core.OutputIdle(winrt::auto_revoke, { get_weak(), &TermControl::_coreOutputIdle }); _revokers.UpdateSelectionMarkers = _core.UpdateSelectionMarkers(winrt::auto_revoke, { get_weak(), &TermControl::_updateSelectionMarkers }); _revokers.coreOpenHyperlink = _core.OpenHyperlink(winrt::auto_revoke, { get_weak(), &TermControl::_HyperlinkHandler }); _revokers.interactivityOpenHyperlink = _interactivity.OpenHyperlink(winrt::auto_revoke, { get_weak(), &TermControl::_HyperlinkHandler }); @@ -534,13 +534,18 @@ 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); } } - _searchBox->Open([searchBox]() { searchBox.SetFocusOnTextbox(); }); + _searchBox->Open([weakThis = get_weak()]() { + if (const auto self = weakThis.get(); !self->_IsClosing()) + { + self->_searchBox->SetFocusOnTextbox(); + self->_refreshSearch(); + } + }); } } } @@ -551,13 +556,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation { return; } - if (!_searchBox) + if (!_searchBox || _searchBox->Visibility() != Visibility::Visible) { CreateSearchBoxControl(); } else { - _core.Search(_searchBox->TextBox().Text(), goForward, false); + _handleSearchResults(_core.Search(_searchBox->Text(), goForward, _searchBox->CaseSensitive(), false)); } } @@ -588,7 +593,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation const bool goForward, const bool caseSensitive) { - _core.Search(text, goForward, caseSensitive); + _handleSearchResults(_core.Search(text, goForward, caseSensitive, false)); } // Method Description: @@ -605,7 +610,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation { if (_searchBox && _searchBox->Visibility() == Visibility::Visible) { - _core.Search(text, goForward, caseSensitive); + _handleSearchResults(_core.Search(text, goForward, caseSensitive, false)); } } @@ -621,6 +626,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation const RoutedEventArgs& /*args*/) { _searchBox->Close(); + _core.ClearSearch(); // Set focus back to terminal control this->Focus(FocusState::Programmatic); @@ -3537,69 +3543,63 @@ namespace winrt::Microsoft::Terminal::Control::implementation return _core.SelectedText(trimTrailingWhitespace); } - // Method Description: - // - Triggers an update on scrollbar to redraw search scroll marks. - // - Called when the search results have changed, and the scroll marks' - // positions need to be updated. - void TermControl::_UpdateSearchScrollMarks() + void TermControl::_refreshSearch() { - // Manually send a scrollbar update, on the UI thread. We're already - // UI-driven, so that's okay. We're not really changing the scrollbar, - // but we do want to update the position of any search marks. The Core - // might send a scrollbar update event too, but if the first search hit - // is in the visible viewport, then the pips won't display until the - // user first scrolls. - auto scrollBar = ScrollBar(); - ScrollBarUpdate update{ - .newValue = scrollBar.Value(), - .newMaximum = scrollBar.Maximum(), - .newMinimum = scrollBar.Minimum(), - .newViewportSize = scrollBar.ViewportSize(), - }; - _throttledUpdateScrollbar(update); + if (!_searchBox || _searchBox->Visibility() != Visibility::Visible) + { + return; + } + + const auto text = _searchBox->Text(); + if (text.empty()) + { + return; + } + + const auto goForward = _searchBox->GoForward(); + const auto caseSensitive = _searchBox->CaseSensitive(); + _handleSearchResults(_core.Search(text, goForward, caseSensitive, true)); } - // Method Description: - // - Called when the core raises a UpdateSearchResults event. That's done in response to: - // - starting a search query with ControlCore::Search. - // - clearing search results due to change in buffer content. - // - The args will tell us if there were or were not any results for that - // particular search. We'll use that to control what to announce to - // Narrator. When we have more elaborate search information to report, we - // may want to report that here. (see GH #3920) - // Arguments: - // - args: contains information about the search state and results that were - // or were not found. - // Return Value: - // - - winrt::fire_and_forget TermControl::_coreUpdateSearchResults(const IInspectable& /*sender*/, Control::UpdateSearchResultsEventArgs args) + void TermControl::_handleSearchResults(SearchResults results) { - co_await wil::resume_foreground(Dispatcher()); - if (auto automationPeer{ Automation::Peers::FrameworkElementAutomationPeer::FromElement(*this) }) + if (!_searchBox) { - automationPeer.RaiseNotificationEvent( - Automation::Peers::AutomationNotificationKind::ActionCompleted, - Automation::Peers::AutomationNotificationProcessing::ImportantMostRecent, - args.FoundMatch() ? RS_(L"SearchBox_MatchesAvailable") : RS_(L"SearchBox_NoMatches"), // what to announce if results were found - L"SearchBoxResultAnnouncement" /* unique name for this group of notifications */); + return; } - _UpdateSearchScrollMarks(); + _searchBox->SetStatus(results.TotalMatches, results.CurrentMatch); - if (_searchBox) + if (results.SearchInvalidated) { - _searchBox->NavigationEnabled(true); - if (args.State() == Control::SearchState::Inactive) + if (_showMarksInScrollbar) { - _searchBox->ClearStatus(); + const auto scrollBar = ScrollBar(); + ScrollBarUpdate update{ + .newValue = scrollBar.Value(), + .newMaximum = scrollBar.Maximum(), + .newMinimum = scrollBar.Minimum(), + .newViewportSize = scrollBar.ViewportSize(), + }; + _updateScrollBar->Run(update); } - else + + if (auto automationPeer{ FrameworkElementAutomationPeer::FromElement(*this) }) { - _searchBox->SetStatus(args.TotalMatches(), args.CurrentMatch()); + automationPeer.RaiseNotificationEvent( + AutomationNotificationKind::ActionCompleted, + AutomationNotificationProcessing::ImportantMostRecent, + results.TotalMatches > 0 ? RS_(L"SearchBox_MatchesAvailable") : RS_(L"SearchBox_NoMatches"), // what to announce if results were found + L"SearchBoxResultAnnouncement" /* unique name for this group of notifications */); } } } + void TermControl::_coreOutputIdle(const IInspectable& /*sender*/, const IInspectable& /*args*/) + { + _refreshSearch(); + } + void TermControl::OwningHwnd(uint64_t owner) { _core.OwningHwnd(owner); diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index 8568cb49b0a..4b7c4a50784 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -371,10 +371,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation double _GetAutoScrollSpeed(double cursorDistanceFromBorder) const; void _Search(const winrt::hstring& text, const bool goForward, const bool caseSensitive); - void _SearchChanged(const winrt::hstring& text, const bool goForward, const bool caseSensitive); void _CloseSearchBoxControl(const winrt::Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& args); - void _UpdateSearchScrollMarks(); + void _refreshSearch(); + void _handleSearchResults(SearchResults results); void _hoveredHyperlinkChanged(const IInspectable& sender, const IInspectable& args); winrt::fire_and_forget _updateSelectionMarkers(IInspectable sender, Control::UpdateSelectionMarkersEventArgs args); @@ -383,7 +383,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation winrt::fire_and_forget _coreTransparencyChanged(IInspectable sender, Control::TransparencyChangedEventArgs args); void _coreRaisedNotice(const IInspectable& s, const Control::NoticeEventArgs& args); void _coreWarningBell(const IInspectable& sender, const IInspectable& args); - winrt::fire_and_forget _coreUpdateSearchResults(const IInspectable& sender, Control::UpdateSearchResultsEventArgs args); + void _coreOutputIdle(const IInspectable& sender, const IInspectable& args); til::point _toPosInDips(const Core::Point terminalCellPos); void _throttledUpdateScrollbar(const ScrollBarUpdate& update); @@ -411,7 +411,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation Control::ControlCore::TransparencyChanged_revoker TransparencyChanged; Control::ControlCore::RaiseNotice_revoker RaiseNotice; Control::ControlCore::HoveredHyperlinkChanged_revoker HoveredHyperlinkChanged; - Control::ControlCore::UpdateSearchResults_revoker UpdateSearchResults; + Control::ControlCore::OutputIdle_revoker OutputIdle; Control::ControlCore::UpdateSelectionMarkers_revoker UpdateSelectionMarkers; Control::ControlCore::OpenHyperlink_revoker coreOpenHyperlink; Control::ControlCore::TitleChanged_revoker TitleChanged; diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index 25ea33fd47b..854d54394d0 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -1230,11 +1230,6 @@ void Microsoft::Terminal::Core::Terminal::CompletionsChangedCallback(std::functi _pfnCompletionsChanged.swap(pfn); } -void Terminal::SetTextLayoutUpdatedCallback(std::function pfn) noexcept -{ - _pfnTextLayoutUpdated.swap(pfn); -} - // Method Description: // - Stores the search highlighted regions in the terminal void Terminal::SetSearchHighlights(const std::vector& highlights) noexcept diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp index 7f1c20789e9..75b822b1386 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -155,7 +155,6 @@ class Microsoft::Terminal::Core::Terminal final : bool IsVtInputEnabled() const noexcept override; void NotifyAccessibilityChange(const til::rect& changedRect) noexcept override; void NotifyBufferRotation(const int delta) override; - void NotifyTextLayoutUpdated() override; void InvokeCompletions(std::wstring_view menuJson, unsigned int replaceLength) override; @@ -231,7 +230,6 @@ class Microsoft::Terminal::Core::Terminal final : void SetShowWindowCallback(std::function pfn) noexcept; void SetPlayMidiNoteCallback(std::function pfn) noexcept; void CompletionsChangedCallback(std::function pfn) noexcept; - void SetTextLayoutUpdatedCallback(std::function pfn) noexcept; void SetSearchHighlights(const std::vector& highlights) noexcept; void SetSearchHighlightFocused(const size_t focusedIdx); @@ -341,7 +339,6 @@ class Microsoft::Terminal::Core::Terminal final : std::function _pfnShowWindowChanged; std::function _pfnPlayMidiNote; std::function _pfnCompletionsChanged; - std::function _pfnTextLayoutUpdated; RenderSettings _renderSettings; std::unique_ptr<::Microsoft::Console::VirtualTerminal::StateMachine> _stateMachine; diff --git a/src/cascadia/TerminalCore/TerminalApi.cpp b/src/cascadia/TerminalCore/TerminalApi.cpp index 07c81649b7c..42f1c903c33 100644 --- a/src/cascadia/TerminalCore/TerminalApi.cpp +++ b/src/cascadia/TerminalCore/TerminalApi.cpp @@ -239,8 +239,6 @@ void Terminal::UseAlternateScreenBuffer(const TextAttribute& attrs) // Update scrollbars _NotifyScrollEvent(); - NotifyTextLayoutUpdated(); - // redraw the screen try { @@ -298,8 +296,6 @@ void Terminal::UseMainScreenBuffer() // Update scrollbars _NotifyScrollEvent(); - NotifyTextLayoutUpdated(); - // redraw the screen _activeBuffer().TriggerRedrawAll(); } @@ -374,15 +370,3 @@ void Terminal::NotifyBufferRotation(const int delta) _NotifyScrollEvent(); } } - -// Method Description: -// - Notifies the terminal UI layer that the text layout has changed. -// - This will be called when new text is added, or when the text is -// rearranged in the buffer due to window resize. -void Terminal::NotifyTextLayoutUpdated() -{ - if (_pfnTextLayoutUpdated) - { - _pfnTextLayoutUpdated(); - } -} diff --git a/src/host/outputStream.cpp b/src/host/outputStream.cpp index 25a2f1fdb2d..fb20d74b75b 100644 --- a/src/host/outputStream.cpp +++ b/src/host/outputStream.cpp @@ -424,12 +424,7 @@ void ConhostInternalGetSet::NotifyBufferRotation(const int delta) } } -void ConhostInternalGetSet::NotifyTextLayoutUpdated() -{ - // Not implemented for conhost. -} - void ConhostInternalGetSet::InvokeCompletions(std::wstring_view /*menuJson*/, unsigned int /*replaceLength*/) { // Not implemented for conhost. -} \ No newline at end of file +} diff --git a/src/host/outputStream.hpp b/src/host/outputStream.hpp index ca5711f6387..01d8abaf17f 100644 --- a/src/host/outputStream.hpp +++ b/src/host/outputStream.hpp @@ -68,7 +68,6 @@ class ConhostInternalGetSet final : public Microsoft::Console::VirtualTerminal:: void NotifyAccessibilityChange(const til::rect& changedRect) override; void NotifyBufferRotation(const int delta) override; - void NotifyTextLayoutUpdated() override; void InvokeCompletions(std::wstring_view menuJson, unsigned int replaceLength) override; diff --git a/src/inc/til/throttled_func.h b/src/inc/til/throttled_func.h index 01c4e356aa3..d250f475af5 100644 --- a/src/inc/til/throttled_func.h +++ b/src/inc/til/throttled_func.h @@ -81,7 +81,7 @@ namespace til }; } // namespace details - template + template class throttled_func { public: @@ -118,15 +118,35 @@ namespace til throttled_func& operator=(throttled_func&&) = delete; // Throttles the invocation of the function passed to the constructor. - // If this is a trailing_throttled_func: - // If you call this function again before the underlying - // timer has expired, the new arguments will be used. + // + // If Debounce is true and you call this function again before the + // underlying timer has expired, its timeout will be reset. + // + // If Leading is true and you call this function again before the + // underlying timer has expired, the new arguments will be used. template void operator()(MakeArgs&&... args) { - if (!_storage.emplace(std::forward(args)...)) + const auto hadValue = _storage.emplace(std::forward(args)...); + + if constexpr (Debounce) { - _leading_edge(); + SetThreadpoolTimerEx(_timer.get(), &_delay, 0, 0); + } + else + { + if (!hadValue) + { + SetThreadpoolTimerEx(_timer.get(), &_delay, 0, 0); + } + } + + if constexpr (Leading) + { + if (!hadValue) + { + _func(); + } } } @@ -165,19 +185,9 @@ namespace til } CATCH_LOG() - void _leading_edge() - { - if constexpr (leading) - { - _func(); - } - - SetThreadpoolTimerEx(_timer.get(), &_delay, 0, 0); - } - void _trailing_edge() { - if constexpr (leading) + if constexpr (Leading) { _storage.reset(); } @@ -187,7 +197,7 @@ namespace til } } - inline wil::unique_threadpool_timer _createTimer() + wil::unique_threadpool_timer _createTimer() { wil::unique_threadpool_timer timer{ CreateThreadpoolTimer(&_timer_callback, this, nullptr) }; THROW_LAST_ERROR_IF(!timer); @@ -201,6 +211,10 @@ namespace til }; template - using throttled_func_trailing = throttled_func; - using throttled_func_leading = throttled_func; + using throttled_func_trailing = throttled_func; + using throttled_func_leading = throttled_func; + + template + using debounced_func_trailing = throttled_func; + using debounced_func_leading = throttled_func; } // namespace til diff --git a/src/renderer/atlas/AtlasEngine.api.cpp b/src/renderer/atlas/AtlasEngine.api.cpp index 9ef05279bf5..674dc3baf7e 100644 --- a/src/renderer/atlas/AtlasEngine.api.cpp +++ b/src/renderer/atlas/AtlasEngine.api.cpp @@ -5,6 +5,7 @@ #include "AtlasEngine.h" #include "Backend.h" +#include "../../buffer/out/textBuffer.hpp" #include "../base/FontCache.h" // #### NOTE #### @@ -95,7 +96,7 @@ constexpr HRESULT vec2_narrow(U x, U y, vec2& out) noexcept return S_OK; } -[[nodiscard]] HRESULT AtlasEngine::InvalidateHighlight(std::span highlights, const std::vector& renditions) noexcept +[[nodiscard]] HRESULT AtlasEngine::InvalidateHighlight(std::span highlights, const TextBuffer& buffer) noexcept { const auto viewportOrigin = til::point{ _api.s->viewportOffset.x, _api.s->viewportOffset.y }; const auto viewport = til::rect{ 0, 0, _api.s->viewportCellCount.x, _api.s->viewportCellCount.y }; @@ -103,7 +104,7 @@ constexpr HRESULT vec2_narrow(U x, U y, vec2& out) noexcept for (const auto& hi : highlights) { hi.iterate_rows(cellCountX, [&](til::CoordType row, til::CoordType beg, til::CoordType end) { - const auto shift = til::at(renditions, row) != LineRendition::SingleWidth ? 1 : 0; + const auto shift = buffer.GetLineRendition(row) != LineRendition::SingleWidth ? 1 : 0; beg <<= shift; end <<= shift; til::rect rect{ beg, row, end + 1, row + 1 }; diff --git a/src/renderer/atlas/AtlasEngine.h b/src/renderer/atlas/AtlasEngine.h index 9f38b7094ff..9ad4425beae 100644 --- a/src/renderer/atlas/AtlasEngine.h +++ b/src/renderer/atlas/AtlasEngine.h @@ -33,7 +33,7 @@ namespace Microsoft::Console::Render::Atlas [[nodiscard]] HRESULT InvalidateCursor(const til::rect* psrRegion) noexcept override; [[nodiscard]] HRESULT InvalidateSystem(const til::rect* prcDirtyClient) noexcept override; [[nodiscard]] HRESULT InvalidateSelection(const std::vector& rectangles) noexcept override; - [[nodiscard]] HRESULT InvalidateHighlight(std::span highlights, const std::vector& renditions) noexcept override; + [[nodiscard]] HRESULT InvalidateHighlight(std::span highlights, const TextBuffer& buffer) noexcept override; [[nodiscard]] HRESULT InvalidateScroll(const til::point* pcoordDelta) noexcept override; [[nodiscard]] HRESULT InvalidateAll() noexcept override; [[nodiscard]] HRESULT InvalidateFlush(_In_ const bool circled, _Out_ bool* const pForcePaint) noexcept override; diff --git a/src/renderer/base/RenderEngineBase.cpp b/src/renderer/base/RenderEngineBase.cpp index 6ab523a1a4d..1847c1d287f 100644 --- a/src/renderer/base/RenderEngineBase.cpp +++ b/src/renderer/base/RenderEngineBase.cpp @@ -7,7 +7,7 @@ using namespace Microsoft::Console; using namespace Microsoft::Console::Render; -[[nodiscard]] HRESULT RenderEngineBase::InvalidateHighlight(std::span /*highlights*/, const std::vector& /*renditions*/) noexcept +[[nodiscard]] HRESULT RenderEngineBase::InvalidateHighlight(std::span /*highlights*/, const TextBuffer& /*renditions*/) noexcept { return S_OK; } diff --git a/src/renderer/base/renderer.cpp b/src/renderer/base/renderer.cpp index deb8925c943..82b1eaea1b4 100644 --- a/src/renderer/base/renderer.cpp +++ b/src/renderer/base/renderer.cpp @@ -459,24 +459,21 @@ void Renderer::TriggerSelection() void Renderer::TriggerSearchHighlight(const std::vector& oldHighlights) try { - const auto& buffer = _pData->GetTextBuffer(); - const auto rows = buffer.TotalRowCount(); + // no need to invalidate focused search highlight separately as they are + // included in (all) search highlights. + const auto newHighlights = _pData->GetSearchHighlights(); - std::vector renditions; - renditions.reserve(rows); - for (til::CoordType row = 0; row < rows; ++row) + if (oldHighlights.empty() && newHighlights.empty()) { - renditions.emplace_back(buffer.GetLineRendition(row)); + return; } - // no need to invalidate focused search highlight separately as they are - // included in (all) search highlights. - const auto newHighlights = _pData->GetSearchHighlights(); + const auto& buffer = _pData->GetTextBuffer(); FOREACH_ENGINE(pEngine) { - LOG_IF_FAILED(pEngine->InvalidateHighlight(oldHighlights, renditions)); - LOG_IF_FAILED(pEngine->InvalidateHighlight(newHighlights, renditions)); + LOG_IF_FAILED(pEngine->InvalidateHighlight(oldHighlights, buffer)); + LOG_IF_FAILED(pEngine->InvalidateHighlight(newHighlights, buffer)); } NotifyPaintFrame(); diff --git a/src/renderer/inc/IRenderEngine.hpp b/src/renderer/inc/IRenderEngine.hpp index 7533de8a4d0..a7afb4244ba 100644 --- a/src/renderer/inc/IRenderEngine.hpp +++ b/src/renderer/inc/IRenderEngine.hpp @@ -67,7 +67,7 @@ namespace Microsoft::Console::Render [[nodiscard]] virtual HRESULT InvalidateCursor(const til::rect* psrRegion) noexcept = 0; [[nodiscard]] virtual HRESULT InvalidateSystem(const til::rect* prcDirtyClient) noexcept = 0; [[nodiscard]] virtual HRESULT InvalidateSelection(const std::vector& rectangles) noexcept = 0; - [[nodiscard]] virtual HRESULT InvalidateHighlight(std::span highlights, const std::vector& renditions) noexcept = 0; + [[nodiscard]] virtual HRESULT InvalidateHighlight(std::span highlights, const TextBuffer& buffer) noexcept = 0; [[nodiscard]] virtual HRESULT InvalidateScroll(const til::point* pcoordDelta) noexcept = 0; [[nodiscard]] virtual HRESULT InvalidateAll() noexcept = 0; [[nodiscard]] virtual HRESULT InvalidateFlush(_In_ const bool circled, _Out_ bool* const pForcePaint) noexcept = 0; diff --git a/src/renderer/inc/RenderEngineBase.hpp b/src/renderer/inc/RenderEngineBase.hpp index 5fd8a94c8a3..1108921edb5 100644 --- a/src/renderer/inc/RenderEngineBase.hpp +++ b/src/renderer/inc/RenderEngineBase.hpp @@ -24,7 +24,7 @@ namespace Microsoft::Console::Render class RenderEngineBase : public IRenderEngine { public: - [[nodiscard]] HRESULT InvalidateHighlight(std::span highlights, const std::vector& renditions) noexcept override; + [[nodiscard]] HRESULT InvalidateHighlight(std::span highlights, const TextBuffer& buffer) noexcept override; [[nodiscard]] HRESULT InvalidateTitle(const std::wstring_view proposedTitle) noexcept override; [[nodiscard]] HRESULT UpdateTitle(const std::wstring_view newTitle) noexcept override; diff --git a/src/terminal/adapter/ITerminalApi.hpp b/src/terminal/adapter/ITerminalApi.hpp index b42ffe283f9..4381c4ecbdd 100644 --- a/src/terminal/adapter/ITerminalApi.hpp +++ b/src/terminal/adapter/ITerminalApi.hpp @@ -80,7 +80,6 @@ namespace Microsoft::Console::VirtualTerminal virtual void NotifyAccessibilityChange(const til::rect& changedRect) = 0; virtual void NotifyBufferRotation(const int delta) = 0; - virtual void NotifyTextLayoutUpdated() = 0; virtual void InvokeCompletions(std::wstring_view menuJson, unsigned int replaceLength) = 0; }; diff --git a/src/terminal/adapter/adaptDispatch.cpp b/src/terminal/adapter/adaptDispatch.cpp index 1a887f99f83..34bc5cd80e6 100644 --- a/src/terminal/adapter/adaptDispatch.cpp +++ b/src/terminal/adapter/adaptDispatch.cpp @@ -182,7 +182,6 @@ void AdaptDispatch::_WriteToBuffer(const std::wstring_view string) // It's important to do this here instead of in TextBuffer, because here you // have access to the entire line of text, whereas TextBuffer writes it one // character at a time via the OutputCellIterator. - _api.NotifyTextLayoutUpdated(); textBuffer.TriggerNewTextNotification(string); } diff --git a/src/terminal/adapter/ut_adapter/adapterTest.cpp b/src/terminal/adapter/ut_adapter/adapterTest.cpp index b17bc4429f9..5cd5fbdc29e 100644 --- a/src/terminal/adapter/ut_adapter/adapterTest.cpp +++ b/src/terminal/adapter/ut_adapter/adapterTest.cpp @@ -215,11 +215,6 @@ class TestGetSet final : public ITerminalApi Log::Comment(L"NotifyBufferRotation MOCK called..."); } - void NotifyTextLayoutUpdated() override - { - Log::Comment(L"NotifyTextLayoutUpdated MOCK called..."); - } - void InvokeCompletions(std::wstring_view menuJson, unsigned int replaceLength) override { Log::Comment(L"InvokeCompletions MOCK called...");