mirror of
https://github.com/microsoft/terminal.git
synced 2026-07-08 18:16:28 +00:00
Fixes xbox controller crashing the Terminal (#20234)
## Summary of the Pull Request Fixes a denial of service by a toddler with an Xbox controller wanting to play Forza. They can impatiently press up and down and close out the terminal window. Issue is upstream in WinUI, but I think this gathers things into a state where Terminal can at least recover by adding a `GettingFocus` handler on the `TabViewItem` that cancels that gamepad focus move before it reaches the framework handler. ## References and Relevant Issues Issue #19671 and #20089 ## Validation Steps Performed Handed a controller to my toddler while working in terminal. I also banged on the keys myself. ## PR Checklist Closes #19671 Closes #20089
This commit is contained in:
1
.github/actions/spelling/allow/microsoft.txt
vendored
1
.github/actions/spelling/allow/microsoft.txt
vendored
@@ -78,4 +78,5 @@ wtl
|
|||||||
wtt
|
wtt
|
||||||
wttlog
|
wttlog
|
||||||
Xamarin
|
Xamarin
|
||||||
|
XBOX
|
||||||
xfgcheck
|
xfgcheck
|
||||||
|
|||||||
@@ -162,6 +162,40 @@ namespace winrt::TerminalApp::implementation
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// BODGY: Work around a fail-fast crash in WinUI 2's TabView. When a
|
||||||
|
// game controller (e.g. an XBOX controller's d-pad/stick) moves focus
|
||||||
|
// Up or Down between two TabViewItems, MUX's TabView::OnListViewGettingFocus
|
||||||
|
// runs a GameController-only code path that calls
|
||||||
|
// DispatcherQueue.TryEnqueue, which fails with E_INVALIDARG. That
|
||||||
|
// unhandled error inside a GettingFocus callback makes XAML fail-fast,
|
||||||
|
// and the whole window vanishes. See
|
||||||
|
// microsoft-ui-xaml/blob/840c6cd4ac9d16d9aa99b24f0bd43997fe21bef8/dev/TabView/TabView.cpp#L246
|
||||||
|
//
|
||||||
|
// This GettingFocus handler is on the TabViewItem, which is closer to
|
||||||
|
// the focus source than the TabViewListView that MUX's handler lives
|
||||||
|
// on, so it runs first. Marking the event Handled - and cancelling the
|
||||||
|
// focus move, which is exactly what MUX itself does for the keyboard
|
||||||
|
// case - preempts MUX's broken handler. Keyboard navigation is left
|
||||||
|
// untouched; MUX handles that path safely.
|
||||||
|
TabViewItem().GettingFocus([](auto&&, const winrt::WUX::Input::GettingFocusEventArgs& args) {
|
||||||
|
const auto direction{ args.Direction() };
|
||||||
|
if (direction != winrt::WUX::Input::FocusNavigationDirection::Up &&
|
||||||
|
direction != winrt::WUX::Input::FocusNavigationDirection::Down)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (args.InputDevice() != winrt::WUX::Input::FocusInputDeviceKind::GameController)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (args.OldFocusedElement().try_as<winrt::MUX::Controls::TabViewItem>() &&
|
||||||
|
args.NewFocusedElement().try_as<winrt::MUX::Controls::TabViewItem>())
|
||||||
|
{
|
||||||
|
args.Cancel(true);
|
||||||
|
args.Handled(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
UpdateTitle();
|
UpdateTitle();
|
||||||
_RecalculateAndApplyTabColor();
|
_RecalculateAndApplyTabColor();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user