Compare commits

...

2 Commits

Author SHA1 Message Date
Carlos Zamora
48bdb8c0ca simplify 2026-05-06 19:27:56 -07:00
Carlos Zamora
42b2ab43d2 Fix crash when closing scratchpad pane 2026-05-06 17:51:50 -07:00
3 changed files with 33 additions and 0 deletions

View File

@@ -997,6 +997,16 @@ void Pane::_ContentLostFocusHandler(const winrt::Windows::Foundation::IInspectab
// - <none>
void Pane::Close()
{
// GH#20187: Make Close() idempotent. The actual removal of this pane
// from the parent's tree is deferred until the close animation in
// _CloseChildRoutine completes (~200ms). Without this guard, a
// second close request that reaches this same pane during the
// animation window would re-raise Closed and kick off a redundant
// close animation on the parent.
if (!_content)
{
return;
}
_setPaneContent(nullptr);
// Fire our Closed event to tell our parent that we should be removed.
Closed.raise(nullptr, nullptr);

View File

@@ -93,6 +93,12 @@ public:
winrt::Windows::UI::Xaml::Controls::Grid GetRootElement();
winrt::TerminalApp::IPaneContent GetContent() const noexcept { return _IsLeaf() ? _content : nullptr; }
// GH#20187: True if this is a leaf pane whose content has already been
// torn down by Pane::Close() but which has not yet been removed from
// its parent (the close animation in _CloseChildRoutine is still
// running). Such a "corpse" pane is not safe to operate on.
bool IsClosed() const noexcept { return _IsLeaf() && _content == nullptr; }
bool WasLastFocused() const noexcept;
void UpdateVisuals();
void ClearActive();

View File

@@ -814,6 +814,23 @@ namespace winrt::TerminalApp::implementation
if (const auto pane{ activeTab->GetActivePane() })
{
// GH#20187: When the user closes a pane with a keyboard
// shortcut, focus moves off the closed pane while keys
// are still depressed. The corresponding KeyUp events
// arrive at TabRowControl, whose KeyUp is wired to
// TerminalPage::_KeyDownHandler (see TerminalPage.xaml).
// _KeyDownHandler can't tell it was invoked from KeyUp
// and dispatches the close action a second time. By
// then the parent's close animation in
// _CloseChildRoutine is still running, so
// Tab::_activePane still points at the now-closed leaf
// ("corpse"). Detect that here and bail before we
// dereference its null content in GetTerminalArgsForPane.
if (pane->IsClosed())
{
co_return;
}
const auto weak = get_weak();
// Check if we should warn before closing a single pane