Skip to content

Commit 8474eb8

Browse files
carlos-zamoraDHowett
authored andcommitted
Update 'restart connection' action to reset internal state (#19971)
## Summary of the Pull Request I was becoming frustrated with getting in a state where a CLI app (i.e. Copilot CLI) enters some VT state (like mouse mode) then doesn't unset it when it accidentally exits. I normally use "Restart connection" to keep the buffer and connect again. Problem is, "restart connection" didn't actually reset the internal state! So I would type and get a bunch of lingering VT escape sequences. This bug is tracked over in #18425 in a more generic way. This fixes that bug by doing the following: - update `ITermDispatch::HardReset()` -->`HardReset(bool erase)` - `erase=true` does what `HardReset()` already did - `erase=false` skips over clearing the screen and resetting the cursor position - expose `HardReset(false)` as `HardResetWithoutErase()` by piping it up through `Terminal` --> `ControlCore` --> `TermControl` - update the restart connection handler - `TerminalPage::_restartPaneConnection()` now calls `HardResetWithoutErase()` before setting the new connection - this is also the same route for the "Enter to restart connection" scenario (text displayed when connection ends) Relevant notes from PR discussion: - `PSEUDOCONSOLE_INHERIT_CURSOR` is passed into the new connection via `_restartPaneConnection()` --> `_duplicateConnectionForRestart()` --> `_CreateConnectionFromSettings(profile, *controlSettings.DefaultSettings(), true)` ## Validation Steps Performed - Used this to enter mouse tracking mode: `Write-Host -NoNewline "`e[?1003h`e[?1006h"` - mouse selection doesn't work as usual (expected) - invoke "restart connection" action - mouse selection works as usual Closes #18425 (cherry picked from commit ec939aa) Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgpBL5w Service-Version: 1.24
1 parent d069ea6 commit 8474eb8

File tree

15 files changed

+58
-15
lines changed

15 files changed

+58
-15
lines changed

src/cascadia/TerminalApp/TerminalPage.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3707,7 +3707,13 @@ namespace winrt::TerminalApp::implementation
37073707
// for nulls
37083708
if (const auto& connection{ _duplicateConnectionForRestart(paneContent) })
37093709
{
3710-
paneContent.GetTermControl().Connection(connection);
3710+
// Reset the terminal's VT state before attaching the new connection.
3711+
// The previous client may have left dirty modes (e.g., bracketed
3712+
// paste, mouse tracking, alternate buffer, kitty keyboard) that
3713+
// would corrupt input/output for the new shell process.
3714+
const auto& termControl = paneContent.GetTermControl();
3715+
termControl.HardResetWithoutErase();
3716+
termControl.Connection(connection);
37113717
connection.Start();
37123718
}
37133719
}

src/cascadia/TerminalControl/ControlCore.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
349349
}
350350
}
351351

352+
void ControlCore::HardResetWithoutErase()
353+
{
354+
const auto lock = _terminal->LockForWriting();
355+
_terminal->HardResetWithoutErase();
356+
}
357+
352358
bool ControlCore::Initialize(const float actualWidth,
353359
const float actualHeight,
354360
const float compositionScale)

src/cascadia/TerminalControl/ControlCore.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
260260

261261
TerminalConnection::ITerminalConnection Connection();
262262
void Connection(const TerminalConnection::ITerminalConnection& connection);
263+
void HardResetWithoutErase();
263264

264265
void AnchorContextMenu(til::point viewportRelativeCharacterPosition);
265266

src/cascadia/TerminalControl/ControlCore.idl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ namespace Microsoft.Terminal.Control
9898
void ApplyAppearance(Boolean focused);
9999

100100
Microsoft.Terminal.TerminalConnection.ITerminalConnection Connection;
101+
void HardResetWithoutErase();
101102

102103
IControlSettings Settings { get; };
103104
IControlAppearance FocusedAppearance { get; };

src/cascadia/TerminalControl/TermControl.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
536536
_core.Connection(newConnection);
537537
}
538538

539+
void TermControl::HardResetWithoutErase()
540+
{
541+
_core.HardResetWithoutErase();
542+
}
543+
539544
void TermControl::_throttledUpdateScrollbar(const ScrollBarUpdate& update)
540545
{
541546
if (!_initializedTerminal)

src/cascadia/TerminalControl/TermControl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
194194

195195
TerminalConnection::ITerminalConnection Connection();
196196
void Connection(const TerminalConnection::ITerminalConnection& connection);
197+
void HardResetWithoutErase();
197198

198199
Control::CursorDisplayState CursorVisibility() const noexcept;
199200
void CursorVisibility(Control::CursorDisplayState cursorVisibility);

src/cascadia/TerminalControl/TermControl.idl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ namespace Microsoft.Terminal.Control
4747
void UpdateControlSettings(IControlSettings settings, IControlAppearance unfocusedAppearance);
4848

4949
Microsoft.Terminal.TerminalConnection.ITerminalConnection Connection;
50+
void HardResetWithoutErase();
5051

5152
UInt64 ContentId{ get; };
5253

src/cascadia/TerminalCore/Terminal.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,18 @@ void Terminal::Create(til::size viewportSize, til::CoordType scrollbackLines, Re
5555
_stateMachine = std::make_unique<StateMachine>(std::move(engine));
5656
}
5757

58+
// Method Description:
59+
// - Resets all VT state to defaults without clearing the buffer content.
60+
// Called when a connection is restarted so that any dirty modes left
61+
// behind by a crashed application don't affect the new connection.
62+
void Terminal::HardResetWithoutErase()
63+
{
64+
_assertLocked();
65+
_stateMachine->ResetState();
66+
auto& engine = reinterpret_cast<OutputStateMachineEngine&>(_stateMachine->Engine());
67+
engine.Dispatch().HardReset(false);
68+
}
69+
5870
// Method Description:
5971
// - Initializes the Terminal from the given set of settings.
6072
// Arguments:

src/cascadia/TerminalCore/Terminal.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ class Microsoft::Terminal::Core::Terminal final :
8686
void Create(til::size viewportSize,
8787
til::CoordType scrollbackLines,
8888
Microsoft::Console::Render::Renderer& renderer);
89+
void HardResetWithoutErase();
8990

9091
void CreateFromSettings(winrt::Microsoft::Terminal::Core::ICoreSettings settings,
9192
Microsoft::Console::Render::Renderer& renderer);

src/terminal/adapter/ITermDispatch.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ class Microsoft::Console::VirtualTerminal::ITermDispatch
135135
virtual void AnnounceCodeStructure(const VTInt ansiLevel) = 0; // ACS
136136

137137
virtual void SoftReset() = 0; // DECSTR
138-
virtual void HardReset() = 0; // RIS
138+
virtual void HardReset(bool erase) = 0; // RIS
139139
virtual void ScreenAlignmentPattern() = 0; // DECALN
140140

141141
virtual void SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) = 0; // DECSCUSR

0 commit comments

Comments
 (0)