From 5b41f146609737e8898aaa2a5bcd1b8eb8cace20 Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Fri, 8 Aug 2025 19:48:52 +0200 Subject: [PATCH] Disable WIN32IM on shutdown (#19229) Closes #19153 ## Validation Steps Performed I tried reproducing the issue on Windows 10 and couldn't. I'm not sure what I did wrong. But I tested it under a debugger with VtPipeTerm and it wrote the sequences to stdout. --- src/host/VtIo.cpp | 22 ++++++++++++++++++++++ src/host/VtIo.hpp | 2 +- src/interactivity/base/ServiceLocator.cpp | 16 +++++----------- src/tools/vtpipeterm/main.cpp | 2 +- 4 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/host/VtIo.cpp b/src/host/VtIo.cpp index 876e3ac8bc..f1a2da2368 100644 --- a/src/host/VtIo.cpp +++ b/src/host/VtIo.cpp @@ -230,6 +230,28 @@ bool VtIo::IsUsingVt() const return S_OK; } +void VtIo::Shutdown() noexcept +{ + if (_state != State::Running) + { + return; + } + + // The reverse of what we did in StartIfNeeded. + try + { + Writer writer{ this }; + + writer.WriteUTF8( + "\x1b[?1004l" // Focus Event Mode + "\x1b[?9001l" // Win32 Input Mode + ); + + writer.Submit(); + } + CATCH_LOG(); +} + void VtIo::RequestCursorPositionFromTerminal() { if (_lookingForCursorPosition) diff --git a/src/host/VtIo.hpp b/src/host/VtIo.hpp index c375cfd843..b8eaaf930e 100644 --- a/src/host/VtIo.hpp +++ b/src/host/VtIo.hpp @@ -57,9 +57,9 @@ namespace Microsoft::Console::VirtualTerminal static wchar_t SanitizeUCS2(wchar_t ch); [[nodiscard]] HRESULT Initialize(const ConsoleArguments* const pArgs); - bool IsUsingVt() const; [[nodiscard]] HRESULT StartIfNeeded(); + void Shutdown() noexcept; void RequestCursorPositionFromTerminal(); void SetDeviceAttributes(til::enumset attributes) noexcept; diff --git a/src/interactivity/base/ServiceLocator.cpp b/src/interactivity/base/ServiceLocator.cpp index 24613d852f..3e882022e7 100644 --- a/src/interactivity/base/ServiceLocator.cpp +++ b/src/interactivity/base/ServiceLocator.cpp @@ -67,13 +67,11 @@ void ServiceLocator::RundownAndExit(const HRESULT hr) Sleep(INFINITE); } - // MSFT:40226902 - HOTFIX shutdown on OneCore, by leaking the renderer, thereby - // reducing the change for existing race conditions to turn into deadlocks. -#ifndef NDEBUG // By locking the console, we ensure no background tasks are accessing the // classes we're going to destruct down below (for instance: CursorBlinker). s_globals.getConsoleInformation().LockConsole(); -#endif + + gci.GetVtIo()->Shutdown(); // A History Lesson from MSFT: 13576341: // We introduced RundownAndExit to give services that hold onto important handles @@ -92,13 +90,6 @@ void ServiceLocator::RundownAndExit(const HRESULT hr) // TODO: MSFT: 14397093 - Expand graceful rundown beyond just the Hot Bug input services case. - // MSFT:40226902 - HOTFIX shutdown on OneCore, by leaking the renderer, thereby - // reducing the change for existing race conditions to turn into deadlocks. -#ifndef NDEBUG - delete s_globals.pRender; - s_globals.pRender = nullptr; -#endif - if (s_oneCoreTeardownFunction) { s_oneCoreTeardownFunction(); @@ -107,6 +98,9 @@ void ServiceLocator::RundownAndExit(const HRESULT hr) // MSFT:40226902 - HOTFIX shutdown on OneCore, by leaking the renderer, thereby // reducing the change for existing race conditions to turn into deadlocks. #ifndef NDEBUG + delete s_globals.pRender; + s_globals.pRender = nullptr; + s_consoleWindow.reset(nullptr); #endif diff --git a/src/tools/vtpipeterm/main.cpp b/src/tools/vtpipeterm/main.cpp index 3117f7aaaa..0a87724727 100644 --- a/src/tools/vtpipeterm/main.cpp +++ b/src/tools/vtpipeterm/main.cpp @@ -89,7 +89,7 @@ static int run(int argc, const wchar_t* argv[]) auto viewportSize = getViewportSize(); HPCON hPC = nullptr; - THROW_IF_FAILED(ConptyCreatePseudoConsole(viewportSize, pipe.client.get(), pipe.client.get(), 0, &hPC)); + THROW_IF_FAILED(ConptyCreatePseudoConsole(viewportSize, pipe.client.get(), pipe.client.get(), PSEUDOCONSOLE_INHERIT_CURSOR, &hPC)); pipe.client.reset(); PROCESS_INFORMATION pi;