From 7f288414b7df8be25b2fa1aa3c1428845f8e2957 Mon Sep 17 00:00:00 2001 From: Carlos Zamora Date: Sat, 21 Jan 2023 07:48:33 -0800 Subject: [PATCH] Ensure TermControl is not closing when firing UIA events (#14714) The `SignalTextChanged` crash seems to be occurring due to the `TermControlAutomationPeer` being destructed by the time the UIA event is actually dispatched. Even though we're already checking if TCAP and TermControl still exist, it could be that the TermControl is being closed as text is being output. The proposed fix here is to record when the closing process starts and exposing that information directly to the TCAP. If TCAP sees that we're in the process of closing, don't bother sending a UIA event. Closes #13978 (cherry picked from commit 3dd40791c961f6227d7ece83299bcac918b689ba) Service-Card-Id: 87728855 Service-Version: 1.16 --- src/cascadia/TerminalControl/TermControl.cpp | 5 +++++ src/cascadia/TerminalControl/TermControlAutomationPeer.cpp | 7 +++++++ src/cascadia/TerminalControl/TermControlAutomationPeer.h | 1 + 3 files changed, 13 insertions(+) diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 535e95b497b..98723932a16 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -1983,6 +1983,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation if (!_IsClosing()) { _closing = true; + if (_automationPeer) + { + auto autoPeerImpl{ winrt::get_self(_automationPeer) }; + autoPeerImpl->Close(); + } _RestorePointerCursorHandlers(*this, nullptr); diff --git a/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp b/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp index 41c55b37640..e9147a77b73 100644 --- a/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp +++ b/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp @@ -117,6 +117,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation } } + void TermControlAutomationPeer::Close() + { + // GH#13978: If the TermControl has already been removed from the UI tree, XAML might run into weird bugs. + // This will prevent the `dispatcher.RunAsync` calls below from raising UIA events on the main thread. + _termControl = {}; + } + // Method Description: // - Signals the ui automation client that the terminal's selection has changed and should be updated // Arguments: diff --git a/src/cascadia/TerminalControl/TermControlAutomationPeer.h b/src/cascadia/TerminalControl/TermControlAutomationPeer.h index e8e62cf953c..be4351fdc15 100644 --- a/src/cascadia/TerminalControl/TermControlAutomationPeer.h +++ b/src/cascadia/TerminalControl/TermControlAutomationPeer.h @@ -49,6 +49,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation void UpdateControlBounds(); void SetControlPadding(const Core::Padding padding); void RecordKeyEvent(const WORD vkey); + void Close(); #pragma region FrameworkElementAutomationPeer hstring GetClassNameCore() const;