Fix CoreWindow being destroyed after handoff (#19298)

As per: https://github.com/microsoft/terminal/discussions/19280#discussioncomment-14237148

## Validation Steps Performed
* Launch wtd via handoff (spawn cmd, etc.)
* Shift+Click the tab bar + button to create a new window
* Close the initial window
* UI doesn't lock up 
This commit is contained in:
Leonard Hecker 2025-09-01 15:32:58 +02:00 committed by GitHub
parent 5899343237
commit 7849b00cbd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -253,6 +253,29 @@ void WindowEmperor::CreateNewWindow(winrt::TerminalApp::WindowRequestedArgs args
_windowCount += 1; _windowCount += 1;
_windows.emplace_back(std::move(host)); _windows.emplace_back(std::move(host));
if (_windowCount == 1)
{
// The first CoreWindow is created implicitly by XAML and parented to the
// first XAML island. We parent it to our initial window for 2 reasons:
// * On Windows 10 the CoreWindow will show up as a visible window on the taskbar
// due to a WinUI bug, and this will hide it, because our initial window is hidden.
// * When we DestroyWindow() the island it will destroy the CoreWindow,
// and it's not possible to recreate it. That's also a WinUI bug.
//
// Note that this must be done after the first window (= first island) is created.
if (const auto coreWindow = winrt::Windows::UI::Core::CoreWindow::GetForCurrentThread())
{
if (const auto interop = coreWindow.try_as<ICoreWindowInterop>())
{
HWND coreHandle = nullptr;
if (SUCCEEDED(interop->get_WindowHandle(&coreHandle)) && coreHandle)
{
SetParent(coreHandle, _window.get());
}
}
}
}
} }
AppHost* WindowEmperor::_mostRecentWindow() const noexcept AppHost* WindowEmperor::_mostRecentWindow() const noexcept
@ -395,24 +418,6 @@ void WindowEmperor::HandleCommandlineArgs(int nCmdShow)
LOG_IF_WIN32_BOOL_FALSE(SetCurrentDirectoryW(system32.c_str())); LOG_IF_WIN32_BOOL_FALSE(SetCurrentDirectoryW(system32.c_str()));
} }
// The first CoreWindow is created implicitly by XAML and parented to the
// first XAML island. We parent it to our initial window for 2 reasons:
// * On Windows 10 the CoreWindow will show up as a visible window on the taskbar
// due to a WinUI bug, and this will hide it, because our initial window is hidden.
// * When we DestroyWindow() the island it will destroy the CoreWindow,
// and it's not possible to recreate it. That's also a WinUI bug.
if (const auto coreWindow = winrt::Windows::UI::Core::CoreWindow::GetForCurrentThread())
{
if (const auto interop = coreWindow.try_as<ICoreWindowInterop>())
{
HWND coreHandle = nullptr;
if (SUCCEEDED(interop->get_WindowHandle(&coreHandle)) && coreHandle)
{
SetParent(coreHandle, _window.get());
}
}
}
{ {
TerminalConnection::ConptyConnection::NewConnection([this](TerminalConnection::ConptyConnection conn) { TerminalConnection::ConptyConnection::NewConnection([this](TerminalConnection::ConptyConnection conn) {
TerminalApp::CommandlineArgs args; TerminalApp::CommandlineArgs args;